Apparatus Version 1.0.0
ECS-like data-driven workflow for Unreal Engine.
BeltSlot.h
1 /*
2  * ░▒▓ APPARATUS ▓▒░
3  *
4  * File: BeltSlot.h
5  * Created: Friday, 23rd October 2020 7:00:48 pm
6  * Author: Vladislav Dmitrievich Turbanov (vladislav@turbanov.ru)
7  * ───────────────────────────────────────────────────────────────────
8  * Last Modified: Friday, 26th March 2021 9:50:00 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 "CoreMinimal.h"
24 #include "UObject/NoExportTypes.h"
25 #include "UObject/WeakInterfacePtr.h"
26 
27 #include "BeltSlotCache.h"
28 #include "Fingerprint.h"
29 #include "Filter.h"
30 
31 #include "BeltSlot.generated.h"
32 
38 USTRUCT(BlueprintType)
39 struct APPARATUSRUNTIME_API FBeltSlot
40 {
41  GENERATED_BODY()
42 
43 public:
44 
48  static const int32 InvalidIndex = -1;
49 
50 private:
51 
53  friend class UBelt;
54 
58  mutable TWeakInterfacePtr<class ISubjective> Subjective = nullptr;
59 
63  UPROPERTY(Meta = (AllowPrivateAccess = "true"))
64  mutable TArray<FBeltSlotCache> Details;
65 
69  mutable int32 DetailsCount = 0;
70 
74  mutable int32 Iteration = 0;
75 
79  mutable int32 IterationsCount = 0;
80 
84  TWeakObjectPtr<class UBelt> Owner;
85 
89  mutable int32 Index = InvalidIndex;
90 
91 public:
92 
96  FORCEINLINE class UBelt* GetOwner() const { return Owner.Get(); }
97 
101  bool IsBuffering() const;
102 
108  FORCEINLINE int32 GetIndex() const { return Index; }
109 
115  FORCEINLINE int32 GetIteration() const { return Iteration; }
116 
120  TScriptInterface<class ISubjective> GetSubjective() const;
121 
125  void SetSubjective(TScriptInterface<class ISubjective> InSubject);
126 
130  void ClearDetails() const;
131 
135  FORCEINLINE FBeltSlot() {}
136 
140  FORCEINLINE FBeltSlot(class UBelt* o, int32 i) : Owner(o), Index(i) {}
141 
145  ~FBeltSlot();
146 
150  FBeltSlot(UBelt* o);
151 
156  bool FetchDetails(const FBeltSlot& Slot, const TArray<int>& Passport);
157 
162  bool FetchDetails(const FBeltSlot& Slot, const TArray<TArray<int>>& Mapping);
163 
167  FORCEINLINE bool IsPresent(const int32 DetailIndex)
168  {
169  if (DetailIndex < 0)
170  return false;
171  if (DetailIndex >= DetailsCount)
172  return false;
173 
174  return Details[DetailIndex].GetDetailsCount() > 0;
175  }
176 
180  UDetail* GetDetail(const int32 DetailIndex) const;
181 
185  UDetail* GetDetail(const TSubclassOf<UDetail> DetailType) const;
186 
190  FORCEINLINE UDetail* operator[](const int32 DetailIndex)
191  {
192  return GetDetail(DetailIndex);
193  }
194 
198  bool FetchDetails();
199 
203  bool FetchDetails(const TArray<class UDetail*>& Details);
204 
208  bool FetchForNext();
209 
213  bool IsValid() const;
214 
218  const FFilter& GetFilter() const;
219 
223  FORCEINLINE operator bool() const { return IsValid(); }
224 
228  FBeltSlot& GetNext();
229 
233  FORCEINLINE bool operator!=(const FBeltSlot& slot) const
234  {
235  return Owner != slot.Owner || Index != slot.Index;
236  }
237 
241  FORCEINLINE bool operator==(const FBeltSlot& slot) const
242  {
243  return Owner == slot.Owner && Index == slot.Index;
244  }
245 
249  FORCEINLINE FBeltSlot& operator=(const FBeltSlot& Slot)
250  {
251  checkf(Owner == Slot.Owner,
252  TEXT("Move-copying slots from different belts is not supported."));
253  checkf(DetailsCount == Slot.DetailsCount,
254  TEXT("Move-copying slots of different details counts is not supported."));
255  check(Index != -1);
256  check(Slot.Index != -1);
257 
258  if (Index == Slot.Index) return *this;
259 
260  for (int32 i = 0; i < Slot.DetailsCount; i++)
261  {
262  Details[i] = Slot.Details[i];
263  }
264 
265  Subjective = Slot.Subjective;
266  IterationsCount = Slot.IterationsCount;
267  Iteration = 0;
268 
269  return *this;
270  }
271 
275  void Reserve();
276 }; // struct FBeltSlot
277 
278 FORCEINLINE FBeltSlot::~FBeltSlot() {}
279 
280 FORCEINLINE UDetail* FBeltSlot::GetDetail(const TSubclassOf<UDetail> DetailType) const
281 {
282  check(DetailType);
283  const FFilter& Filter = GetFilter();
284  const int32 TypeIndex = Filter.IndexOf(DetailType);
285  checkf(TypeIndex >= 0, TEXT("Invalid index for type: %s"),
286  *DetailType->GetName());
287  return GetDetail(TypeIndex);
288 }
289 
290 FORCEINLINE TScriptInterface<class ISubjective> FBeltSlot::GetSubjective() const
291 {
292  if (Subjective.IsValid())
293  {
294  return Subjective.ToScriptInterface();
295  }
296  ClearDetails();
297  return nullptr;
298 }
299 
300 FORCEINLINE void FBeltSlot::ClearDetails() const
301 {
302  for (int32 i = 0; i < DetailsCount; i++)
303  {
304  Details[i].Reset();
305  }
306  DetailsCount = 0;
307  IterationsCount = 0;
308 }
309 
310 FORCEINLINE void FBeltSlot::SetSubjective(TScriptInterface<ISubjective> InSubjective)
311 {
312  if (Subjective == TWeakInterfacePtr<ISubjective>(*InSubjective))
313  {
314  // Nothing needs to be changed:
315  return;
316  }
317 
318  Subjective = InSubjective;
319  ClearDetails();
320 }
The conveyor belt consisting of subjects.
Definition: Belt.h:60
void FetchDetails()
Fetch all of the current active details in this belt.
Definition: Belt.cpp:267
friend struct FBeltSlot
Definition: Belt.h:208
bool IsBuffering() const
Is this a special belt, used for buffering other belts?
Definition: Belt.h:101
const FFilter & GetFilter() const
The active filter of the belt.
Definition: Belt.h:111
The base subject detail (component) class.
Definition: Detail.h:35
Definition: SubjectiveActorComponent.h:39
A detail caching for subjects used in the belts' slots.
Definition: BeltSlotCache.h:34
The belt slot, containing the cached details.
Definition: BeltSlot.h:40
bool FetchDetails(const TArray< class UDetail * > &Details)
Fetch the details from the list of details supplied.
bool IsPresent(const int32 DetailIndex)
Does detail at specified index exist?
Definition: BeltSlot.h:167
UDetail * GetDetail(const int32 DetailIndex) const
Get the detail by its index.
Definition: BeltSlot.cpp:389
int32 GetIteration() const
The current iteration of the slot.
Definition: BeltSlot.h:115
TScriptInterface< class ISubjective > GetSubjective() const
Get the subjective of the slot.
Definition: BeltSlot.h:290
FBeltSlot(class UBelt *o, int32 i)
The main slot constructor.
Definition: BeltSlot.h:140
int32 GetIndex() const
Get the index of the slot in the belt.
Definition: BeltSlot.h:108
FBeltSlot & operator=(const FBeltSlot &Slot)
Assignment operator.
Definition: BeltSlot.h:249
void ClearDetails() const
Clear all of the cached details in the slot.
Definition: BeltSlot.h:300
UDetail * operator[](const int32 DetailIndex)
Get the detail by its index.
Definition: BeltSlot.h:190
const FFilter & GetFilter() const
The active filter of the slot, which is the same as its owning belt's.
Definition: Belt.h:570
void SetSubjective(TScriptInterface< class ISubjective > InSubject)
Set the subjective of the slot.
Definition: BeltSlot.h:310
FBeltSlot()
The default slot constructor.
Definition: BeltSlot.h:135
~FBeltSlot()
Deinitialize the belt slot.
Definition: BeltSlot.h:278
bool operator==(const FBeltSlot &slot) const
Compare two belt slots for equality.
Definition: BeltSlot.h:241
bool operator!=(const FBeltSlot &slot) const
Compare two belt slots for inequality.
Definition: BeltSlot.h:233
The details filter specification.
Definition: Filter.h:44
int32 IndexOf(const TSubclassOf< class UDetail > DetailType) const
Get the index of a specific detail type.
Definition: Filter.h:179