UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
DataTable.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_4
6#include "CoreMinimal.h"
7#endif //UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_4
9#include "UObject/Object.h"
10#include "UObject/Class.h"
11#include "UObject/UnrealType.h"
14#include "DataTableUtils.h"
15#include "DataTable.generated.h"
16
17class Error;
18class UDataTable;
19struct FDataTableEditorUtils;
20class UGameplayTagTableManager;
23template <class CharType> struct TPrettyJsonPrintPolicy;
24
25// forward declare JSON writer
26template <class CharType>
28template <class CharType, class PrintPolicy>
29class TJsonWriter;
30
31
35USTRUCT(BlueprintInternalUseOnly)
37{
39
41 virtual ~FTableRowBase() { }
42
52
62
63#if WITH_EDITOR
71#endif // WITH_EDITOR
72};
73
74
78UCLASS(MinimalAPI, BlueprintType, AutoExpandCategories = "DataTable,ImportOptions", Meta = (LoadBehavior = "LazyOnDemand"))
81{
83
86
87 friend FDataTableEditorUtils;
88 friend UGameplayTagTableManager;
91
93 UPROPERTY(VisibleAnywhere, Category=DataTable, meta=(DisplayThumbnail="false"))
95
96protected:
99
100 // TODO: remove this, it is temporarily here to allow DataTableEditorUtils to compile until I get around to updating functions like RemoveRow and RenameRow
101 virtual TMap<FName, uint8*>& GetNonConstRowMap() { return RowMap; }
102
104 ENGINE_API virtual void AddRowInternal(FName RowName, uint8* RowDataPtr);
105
107 ENGINE_API virtual void RemoveRowInternal(FName RowName);
108public:
109
110 virtual const TMap<FName, uint8*>& GetRowMap() const { return RowMap; }
111 virtual const TMap<FName, uint8*>& GetRowMap() { return RowMap; }
112
113 const UScriptStruct* GetRowStruct() const { return RowStruct; }
114
116 virtual bool AllowDuplicateRowsOnImport() const { return false; }
117
119 UPROPERTY(EditAnywhere, Category=DataTable)
120 uint8 bStripFromClientBuilds : 1;
121
123 UPROPERTY(EditAnywhere, Category=ImportOptions)
124 uint8 bIgnoreExtraFields : 1;
125
127 UPROPERTY(EditAnywhere, Category = ImportOptions)
128 uint8 bIgnoreMissingFields : 1;
129
131 UPROPERTY(EditAnywhere, Category = ImportOptions)
132 uint8 bPreserveExistingValues : 1;
133
135 UPROPERTY(EditAnywhere, Category=ImportOptions)
136 FString ImportKeyField;
137
138#if WITH_EDITOR
139 ENGINE_API virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
140 ENGINE_API virtual EDataValidationResult IsDataValid(FDataValidationContext& Context) const override;
141protected:
143public:
144#endif // WITH_EDITOR
145
146 //~ Begin UObject Interface.
147 ENGINE_API virtual void FinishDestroy() override;
148 ENGINE_API virtual void Serialize(FStructuredArchiveRecord Record) override;
149 ENGINE_API static void AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector);
150 ENGINE_API virtual void GetPreloadDependencies(TArray<UObject*>& OutDeps) override;
151 ENGINE_API virtual void GetResourceSizeEx(FResourceSizeEx& CumulativeResourceSize) override;
152 virtual bool NeedsLoadForClient() const override { return bStripFromClientBuilds ? false : Super::NeedsLoadForClient(); }
153 virtual bool NeedsLoadForEditorGame() const override { return bStripFromClientBuilds ? false : Super::NeedsLoadForEditorGame(); }
154#if WITH_EDITORONLY_DATA
156 ENGINE_API virtual void GetAssetRegistryTags(FAssetRegistryTagsContext Context) const override;
157 UE_DEPRECATED(5.4, "Implement the version that takes FAssetRegistryTagsContext instead.")
158 ENGINE_API virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override;
159 ENGINE_API virtual void PostInitProperties() override;
161 //~ End UObject Interface
162
164 UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSource)
166
168 UPROPERTY()
169 FString ImportPath_DEPRECATED;
170
172 UPROPERTY()
174
176 UPROPERTY()
178
183
186#endif // WITH_EDITORONLY_DATA
187
188private:
190 FOnDataTableChanged OnDataTableChangedDelegate;
191
192public:
194 FOnDataTableChanged& OnDataTableChanged() { return OnDataTableChangedDelegate; }
195
200 ENGINE_API void HandleDataTableChanged(FName ChangedRowName = NAME_None);
201
203 template <class T>
205 {
206 if (CommonTypeCheck(T::StaticStruct(), TEXT("UDataTable::GetAllRows"), ContextString))
207 {
208 OutRowArray.Reserve(OutRowArray.Num() + GetRowMap().Num());
209 for (TMap<FName, uint8*>::TConstIterator RowMapIter(GetRowMap().CreateConstIterator()); RowMapIter; ++RowMapIter)
210 {
211 OutRowArray.Add(reinterpret_cast<T*>(RowMapIter.Value()));
212 }
213 }
214 }
215
216 template <class T>
221
223 template <class T>
224 T* FindRow(FName RowName, const TCHAR* ContextString, bool bWarnIfRowMissing = true) const
225 {
226 return reinterpret_cast<T*>(FindRowInternal(T::StaticStruct(), RowName, ContextString, bWarnIfRowMissing));
227 }
228
229 template <class T>
230 T* FindRow(FName RowName, const FString& ContextString, bool bWarnIfRowMissing = true) const
231 {
232 return FindRow<T>(RowName, *ContextString, bWarnIfRowMissing);
233 }
234
236 template <class T>
237 void ForeachRow(const TCHAR* ContextString, TFunctionRef<void (const FName& Key, const T& Value)> Predicate) const
238 {
239 if (CommonTypeCheck(T::StaticStruct(), TEXT("UDataTable::ForeachRow"), ContextString))
240 {
241 for (TMap<FName, uint8*>::TConstIterator RowMapIter(GetRowMap().CreateConstIterator()); RowMapIter; ++RowMapIter)
242 {
243 T* Entry = reinterpret_cast<T*>(RowMapIter.Value());
244 Predicate(RowMapIter.Key(), *Entry);
245 }
246 }
247 }
248
249 template <class T>
250 void ForeachRow(const FString& ContextString, TFunctionRef<void (const FName& Key, const T& Value)> Predicate) const
251 {
252 ForeachRow<T>(*ContextString, Predicate);
253 }
254
256 ENGINE_API FProperty* FindTableProperty(const FName& PropertyName) const;
257
260 {
261 if(RowStruct == nullptr)
262 {
263 return nullptr;
264 }
265
266 // If is RowName is none, it won't find anything in the map
267 uint8* const* RowDataPtr = GetRowMap().Find(RowName);
268
269 if(RowDataPtr == nullptr)
270 {
271 return nullptr;
272 }
273
274 return *RowDataPtr;
275 }
276
278 ENGINE_API virtual void EmptyTable();
279
280 ENGINE_API TArray<FName> GetRowNames() const;
281
283 ENGINE_API virtual void RemoveRow(FName RowName);
284
286 ENGINE_API virtual void AddRow(FName RowName, const FTableRowBase& RowData);
287 ENGINE_API virtual void AddRow(FName RowName, const uint8* RowData, const UScriptStruct* RowType);
288
289#if WITH_EDITOR
290 ENGINE_API virtual void CleanBeforeStructChange();
292
294 ENGINE_API FString GetTableAsString(const EDataTableExportFlags InDTExportFlags = EDataTableExportFlags::None) const;
295
298
301
303 template<typename CharType = TCHAR>
304 bool WriteTableAsJSON(const TSharedRef< TJsonWriter<CharType, TPrettyJsonPrintPolicy<CharType> > >& JsonWriter, const EDataTableExportFlags InDTExportFlags = EDataTableExportFlags::None) const;
305
307 template<typename CharType = TCHAR>
309
311 template<typename CharType = TCHAR>
313
316#endif
322 ENGINE_API TArray<FString> CreateTableFromCSVString(const FString& InString);
323
329 ENGINE_API TArray<FString> CreateTableFromJSONString(const FString& InString);
330
332 TArray<FProperty*> GetTablePropertyArray(const TArray<const TCHAR*>& Cells, UStruct* RowStruct, TArray<FString>& OutProblems, int32 KeyColumn = 0);
333
338 ENGINE_API TArray<FString> CreateTableFromOtherTable(const UDataTable* InTable);
339
345
346#if WITH_EDITOR
349
352
355#endif //WITH_EDITOR
356
357 //~ End UDataTable Interface
358
359protected:
360 void SaveStructData(FStructuredArchiveSlot Slot);
361 void LoadStructData(FStructuredArchiveSlot Slot);
362
369 void OnPostDataImported(OUT TArray<FString>& OutCollectedImportProblems);
370
371 UScriptStruct& GetEmptyUsingStruct() const;
372
375 {
379
380 private:
382 FName RowName;
383 static TMap<UDataTable*, int32> ScopeCount;
384 static FTransactionallySafeCriticalSection CriticalSection;
385 };
386
387private:
388 ENGINE_API bool CommonTypeCheck(UScriptStruct* Type, const TCHAR* MethodName, const TCHAR* ContextString) const;
389 ENGINE_API uint8* FindRowInternal(UScriptStruct* Type, FName RowName, const TCHAR* ContextString, bool bWarnIfRowMissing) const;
390};
391
392
394USTRUCT(BlueprintType)
396{
398
400 : DataTable(nullptr)
401 , RowName(NAME_None)
402 {
403
404 }
405
407 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=DataTableRowHandle)
409
411 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=DataTableRowHandle)
412 FName RowName;
413
415 bool IsNull() const
416 {
417 return DataTable == nullptr && RowName.IsNone();
418 }
419
421 template <class T>
422 T* GetRow(const TCHAR* ContextString) const
423 {
424 if(DataTable == nullptr)
425 {
426 if (RowName != NAME_None)
427 {
428 UE_LOG(LogDataTable, Warning, TEXT("FDataTableRowHandle::GetRow : No DataTable for row %s (%s)."), *RowName.ToString(), ContextString);
429 }
430 return nullptr;
431 }
432
433 return DataTable->FindRow<T>(RowName, ContextString);
434 }
435
436 template <class T>
437 T* GetRow(const FString& ContextString) const
438 {
439 return GetRow<T>(*ContextString);
440 }
441
442 FString ToDebugString(bool bUseFullPath = false) const
443 {
444 if (DataTable == nullptr)
445 {
446 return FString::Printf(TEXT("No Data Table Specified, Row: %s"), *RowName.ToString());
447 }
448
449 return FString::Printf(TEXT("Table: %s, Row: %s"), bUseFullPath ? *DataTable->GetPathName() : *DataTable->GetName(), *RowName.ToString());
450 }
451
452 ENGINE_API bool operator==(FDataTableRowHandle const& Other) const;
454 ENGINE_API void PostSerialize(const FArchive& Ar);
455};
456
457template<>
459{
460 enum
461 {
463 };
464};
465
467USTRUCT(BlueprintType)
469{
471
472
473 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=DataTableCategoryHandle)
474 TObjectPtr<const class UDataTable> DataTable = nullptr;
475
477 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=DataTableCategoryHandle)
478 FName ColumnName;
479
481 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=DataTableCategoryHandle)
482 FName RowContents;
483
485 bool IsNull() const
486 {
487 return DataTable == nullptr && ColumnName == NAME_None && RowContents == NAME_None;
488 }
489
491 template <class T>
492 void GetRows(TArray<T*>& OutRows, const FString& ContextString) const
493 {
494 OutRows.Empty();
495 if (DataTable == nullptr)
496 {
497 if (RowContents != NAME_None)
498 {
499 UE_LOG(LogDataTable, Warning, TEXT("FDataTableCategoryHandle::GetRows : No DataTable for row %s (%s)."), *RowContents.ToString(), *ContextString);
500 }
501
502 return;
503 }
504
505 if (ColumnName == NAME_None)
506 {
507 if (RowContents != NAME_None)
508 {
509 UE_LOG(LogDataTable, Warning, TEXT("FDataTableCategoryHandle::GetRows : No Column selected for row %s (%s)."), *RowContents.ToString(), *ContextString);
510 }
511
512 return;
513 }
514
515 // Find the property that matches the desired column (ColumnName)
516 FProperty* Property = DataTable->FindTableProperty(ColumnName);
517 if (Property == nullptr)
518 {
519 return;
520 }
521
522 // check each row to see if the value in the Property element is the one we're looking for (RowContents). If it is, add the row to OutRows
525 if (Property->ImportText_Direct(*RowContents.ToString(), RowContentsAsBinary, nullptr, PPF_None) == nullptr)
526 {
527 Property->DestroyValue(RowContentsAsBinary);
528 return;
529 }
530
531 for (auto RowIt = DataTable->GetRowMap().CreateConstIterator(); RowIt; ++RowIt)
532 {
533 uint8* RowData = RowIt.Value();
534
535 if (Property->Identical(Property->ContainerPtrToValuePtr<void>(RowData, 0), RowContentsAsBinary, PPF_None))
536 {
537 OutRows.Add((T*)RowData);
538 }
539 }
540 Property->DestroyValue(RowContentsAsBinary);
541
542 return;
543 }
544
545 ENGINE_API bool operator==(FDataTableCategoryHandle const& Other) const;
547};
548
549
551#define GETROW_REPORTERROR(Handle, Template) Handle.GetRow<Template>(FString::Printf(TEXT("%s.%s"), *GetPathName(), TEXT(#Handle)))
552#define GETROWOBJECT_REPORTERROR(Object, Handle, Template) Handle.GetRow<Template>(FString::Printf(TEXT("%s.%s"), *Object->GetPathName(), TEXT(#Handle)))
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define OUT
Definition Platform.h:897
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
EDataTableExportFlags
Definition DataTableUtils.h:13
#define DECLARE_MULTICAST_DELEGATE(DelegateName)
Definition DelegateCombinations.h:23
#define FMemory_Alloca(Size)
Definition GenericPlatformMemory.h:218
UE_FORCEINLINE_HINT bool operator!=(const FIndexedPointer &Other) const
Definition LockFreeList.h:76
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
@ Num
Definition MetalRHIPrivate.h:234
#define UPROPERTY(...)
UObject definition macros.
Definition ObjectMacros.h:744
#define GENERATED_UCLASS_BODY(...)
Definition ObjectMacros.h:768
#define UCLASS(...)
Definition ObjectMacros.h:776
#define USTRUCT(...)
Definition ObjectMacros.h:746
#define GENERATED_USTRUCT_BODY(...)
Definition ObjectMacros.h:767
@ PPF_None
Definition PropertyPortFlags.h:15
::FCriticalSection FTransactionallySafeCriticalSection
Definition TransactionallySafeCriticalSection.h:16
EDataValidationResult
Definition UObjectGlobals.h:4225
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition Archive.h:1208
Definition AssetRegistryTagsContext.h:98
Definition DataTableCSV.h:34
Definition DataTableJSON.h:86
Definition DataValidation.h:40
Definition NameTypes.h:617
FORCEINLINE bool IsNone() const
Definition NameTypes.h:827
Definition UnrealType.h:174
void InitializeValue(void *Dest) const
Definition UnrealType.h:1108
Definition UObjectGlobals.h:2492
Definition StructuredArchiveSlots.h:144
Definition StructuredArchiveSlots.h:52
Definition Array.h:670
Definition AssetRegistryState.h:50
Definition JsonWriter.h:85
Definition UnrealString.h.inl:34
Definition SharedPointer.h:153
Definition AssetImportData.h:72
Definition DataTable.h:81
void ForeachRow(const FString &ContextString, TFunctionRef< void(const FName &Key, const T &Value)> Predicate) const
Definition DataTable.h:250
virtual TMap< FName, uint8 * > & GetNonConstRowMap()
Definition DataTable.h:101
void GetAllRows(const TCHAR *ContextString, OUT TArray< T * > &OutRowArray) const
Definition DataTable.h:204
virtual const TMap< FName, uint8 * > & GetRowMap()
Definition DataTable.h:111
virtual bool AllowDuplicateRowsOnImport() const
Definition DataTable.h:116
uint8 * FindRowUnchecked(FName RowName) const
Definition DataTable.h:259
virtual bool NeedsLoadForClient() const override
Definition DataTable.h:152
void ForeachRow(const TCHAR *ContextString, TFunctionRef< void(const FName &Key, const T &Value)> Predicate) const
Definition DataTable.h:237
TMap< FName, uint8 * > RowMap
Definition DataTable.h:98
T * FindRow(FName RowName, const FString &ContextString, bool bWarnIfRowMissing=true) const
Definition DataTable.h:230
FOnDataTableChanged & OnDataTableChanged()
Definition DataTable.h:194
T * FindRow(FName RowName, const TCHAR *ContextString, bool bWarnIfRowMissing=true) const
Definition DataTable.h:224
void GetAllRows(const FString &ContextString, OUT TArray< T * > &OutRowArray) const
Definition DataTable.h:217
const UScriptStruct * GetRowStruct() const
Definition DataTable.h:113
virtual const TMap< FName, uint8 * > & GetRowMap() const
Definition DataTable.h:110
virtual bool NeedsLoadForEditorGame() const override
Definition DataTable.h:153
Definition Object.h:95
Definition Class.h:1720
Definition Class.h:480
@ false
Definition radaudio_common.h:23
Definition DataTable.h:469
void GetRows(TArray< T * > &OutRows, const FString &ContextString) const
Definition DataTable.h:492
Definition DataTable.h:396
T * GetRow(const TCHAR *ContextString) const
Definition DataTable.h:422
T * GetRow(const FString &ContextString) const
Definition DataTable.h:437
FString ToDebugString(bool bUseFullPath=false) const
Definition DataTable.h:442
Definition UnrealType.h:6865
Definition ResourceSize.h:31
Definition DataTable.h:37
virtual ~FTableRowBase()
Definition DataTable.h:41
virtual void OnPostDataImport(const UDataTable *InDataTable, const FName InRowName, TArray< FString > &OutCollectedImportProblems)
Definition DataTable.h:51
virtual void OnDataTableChanged(const UDataTable *InDataTable, const FName InRowName)
Definition DataTable.h:61
Definition TopLevelAssetPath.h:38
Definition ObjectPtr.h:488
Definition PrettyJsonPrintPolicy.h:16
Definition StructOpsTypeTraits.h:11
@ WithPostSerialize
Definition StructOpsTypeTraits.h:25
Definition StructOpsTypeTraits.h:46
Definition DataTable.h:375