UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CookDependency.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if WITH_EDITOR
9#include "Hash/Blake3.h"
12#include "Templates/Function.h"
13#include "Templates/UniquePtr.h"
14#include "UObject/NameTypes.h"
15
16class FCbFieldView;
17class FCbWriter;
18class UObject;
19namespace UE::ConfigAccessTracking { enum class ELoadType : uint8; }
21namespace UE::Cook { class FConsoleVariableData; }
22namespace UE::Cook { struct FCookDependencyContext; }
23struct FARFilter;
24#endif
25
26#if WITH_EDITOR
27
28namespace UE::Cook
29{
34enum class ECookDependency : uint8
35{
36 None = 0,
37 File = 1,
38 Function = 2,
40 Package = 4,
41 ConsoleVariable = 5,
42 Config = 6,
44 NativeClass = 8,
47
48 Count,
49};
51
52namespace ResultProjection
53{
61/*
62 * FName passed into FCookDependency::ResultProjection or UE_COOK_RESULTPROJECTION_SCOPED to indicate the bytes
63 * within the target package, and the native class used by objects referenced from it, can contribute to the
64 * source package's cook. This is more limited than the transitive dependency indicated by BuildProjectionAll
65 * because it does not include e.g. other packages that the target package depends on for its cook.
66 * This ResultProjection is applied automatically for all hard imports saved into the source cooked package;
67 * the SavePackage code applies it because generic LinkerLoad code can cause those imports to be included
68 * or excluded from the package based on values of e.g. NeedsLoadForClient.
69 */
71/*
72 * FName passed into UE_COOK_RESULTPROJECTION_SCOPED to indicate that dereferences of TObjectPtr within the scope
73 * should not be automatically added as dependencies of any kind. The calling code for those scopes either
74 * knows that the resolves are spurious or is declaring the proper ResultProjection dependency manually.
75 */
77
78}
79
92namespace BuildResult
93{
94
97
103
104}
105
112class FCookDependency
113{
114public:
132
139 UE_DEPRECATED(5.6, "Add a TransitiveBuild and a Runtime dependency separately.")
141
147
152 COREUOBJECT_API static FCookDependency ConsoleVariable(const FStringView& VariableName);
153 COREUOBJECT_API static FCookDependency ConsoleVariable(const FStringView& VariableName, const ITargetPlatform* TargetPlatform, bool bFallbackToNonPlatform);
154
158 FName FileName, FName SectionName, FName ValueName);
160 COREUOBJECT_API static FCookDependency Config(FName FileName, FName SectionName, FName ValueName);
161
171
174 COREUOBJECT_API static FCookDependency NativeClass(FStringView ClassPath);
175
178
181
184
190
192 ECookDependency GetType() const;
193
195 COREUOBJECT_API FString GetDebugIdentifier() const;
196
198 FStringView GetFileName() const;
199
201 FName GetFunctionName() const;
204
206 FName GetPackageName() const;
208 bool IsAlsoAddRuntimeDependency() const;
209
211 COREUOBJECT_API UE::ConfigAccessTracking::FConfigAccessData GetConfigAccessData() const;
216 COREUOBJECT_API FString GetConfigPath() const;
217
222 const UObject* GetSettingsObject() const;
223
229
231 const FARFilter* GetARFilter() const;
232
234 const uint8* GetRawValue() const;
236 const FBlake3Hash& GetHashValue() const;
237
242 bool operator<(const FCookDependency& Other) const;
244 bool operator==(const FCookDependency& Other) const;
245 bool operator!=(const FCookDependency& Other) const;
246
249
250 COREUOBJECT_API void SetValue(const FBlake3Hash& Hash);
251 void SetValue(const FIoHash& Hash);
252 void SetValue(const FUtf8String& String);
253
256
257 static const uint8 ValueSizeInBytes = 32;
258
259private:
261 void Construct();
262 void Destruct();
263 COREUOBJECT_API void Save(FCbWriter& Writer) const;
265 static COREUOBJECT_API bool ConfigAccessDataLessThan(const UE::ConfigAccessTracking::FConfigAccessData& A,
266 const UE::ConfigAccessTracking::FConfigAccessData& B);
267 static COREUOBJECT_API bool ConfigAccessDataEqual(const UE::ConfigAccessTracking::FConfigAccessData& A,
268 const UE::ConfigAccessTracking::FConfigAccessData& B);
271
274
276 friend FCbWriter& operator<<(FCbWriter& Writer, const FCookDependency& CookDependency)
277 {
278 CookDependency.Save(Writer);
279 return Writer;
280 }
283 {
284 return CookDependency.Load(Value);
285 }
286
287private:
289 struct FFunctionData
290 {
291 FName Name;
292 FCbFieldIterator Args;
293 };
295 {
296 FName PackageName;
297 bool bAlsoAddRuntimeDependency = false;
298 };
299 union
300 {
301 FString StringData;
304 FName NameData;
305 const UObject* ObjectPtr;
309 };
310
315 union
316 {
317 uint8 RawValue[ValueSizeInBytes];
319 };
320};
321
334
335} // namespace UE::Cook
336
337namespace UE::Cook::Dependency::Private
338{
339
346{
347 template<int N>
349 : Name(InName), Function(InFunction), Next(nullptr)
350 {
351 static_assert(N > 0, "Name must be provided");
352 check(InName[0] != '\0');
353 Construct();
354 }
357 FName GetFName();
358
362};
363
364} // namespace UE::Cook::Dependency::Private
365
375#define UE_COOK_DEPENDENCY_FUNCTION(Name, Function) \
376 UE::Cook::Dependency::Private::FCookDependencyFunctionRegistration \
377 PREPROCESSOR_JOIN(FCookDependencyFunctionRegistration_,Name)(TEXT(#Name), Function)
382#define UE_COOK_DEPENDENCY_FUNCTION_CALL(Name) \
383 PREPROCESSOR_JOIN(FCookDependencyFunctionRegistration_,Name).GetFName()
384
385#else // WITH_EDITOR
386
387#define UE_COOK_RESULTPROJECTION_SCOPED(ProjectionName)
388#define UE_COOK_DEPENDENCY_FUNCTION(Name, Function)
389#define UE_COOK_DEPENDENCY_FUNCTION_CALL(Name) NAME_None
390
391#endif // !WITH_EDITOR
392
393#if WITH_EDITOR
394namespace UE::Cook
395{
396inline ECookDependency FCookDependency::GetType() const
397{
398 return Type;
399}
400
401inline FStringView FCookDependency::GetFileName() const
402{
403 return Type == ECookDependency::File ? StringData : FStringView();
404}
405
406inline FName FCookDependency::GetFunctionName() const
407{
408 return Type == ECookDependency::Function ? FunctionData.Name : NAME_None;
409}
410
411inline FCbFieldViewIterator FCookDependency::GetFunctionArgs() const
412{
413 return Type == ECookDependency::Function ? FunctionData.Args : FCbFieldViewIterator();
414}
415
416inline FName FCookDependency::GetPackageName() const
417{
419 switch (GetType())
420 {
421 case ECookDependency::TransitiveBuild:
422 return TransitiveBuildData.PackageName;
423 case ECookDependency::Package:
424 return NameData;
425 case ECookDependency::RedirectionTarget:
426 return NameData;
427 default:
428 return NAME_None;
429 };
431}
432
433inline bool FCookDependency::IsAlsoAddRuntimeDependency() const
434{
436 return Type == ECookDependency::TransitiveBuild ? TransitiveBuildData.bAlsoAddRuntimeDependency : false;
438}
439
440inline const UObject* FCookDependency::GetSettingsObject() const
441{
442 return Type == ECookDependency::SettingsObject ? ObjectPtr : nullptr;
443}
444
445inline FStringView FCookDependency::GetClassPath() const
446{
447 return Type == ECookDependency::NativeClass ? StringData : FStringView();
448}
449
450inline const FARFilter* FCookDependency::GetARFilter() const
451{
452 return Type == ECookDependency::AssetRegistryQuery ? ARFilter.Get() : nullptr;
453}
454
455inline const uint8* FCookDependency::GetRawValue() const
456{
457 return RawValue;
458}
459
460inline const FBlake3Hash& FCookDependency::GetHashValue() const
461{
462 return HashedValue;
463}
464
465inline bool FCookDependency::operator<(const FCookDependency& Other) const
466{
467 if (static_cast<uint8>(Type) != static_cast<uint8>(Other.Type))
468 {
469 return static_cast<uint8>(Type) < static_cast<uint8>(Other.Type);
470 }
471
472 switch (Type)
473 {
474 case ECookDependency::None:
475 return false;
476 case ECookDependency::File:
477 case ECookDependency::NativeClass:
478 return StringData.Compare(Other.StringData, ESearchCase::IgnoreCase) < 0;
479
480 case ECookDependency::ConsoleVariable:
481 {
482 if (ConsoleVariableData.IsValid() != Other.ConsoleVariableData.IsValid())
483 {
484 return !ConsoleVariableData.IsValid();
485 }
486
487 if (ConsoleVariableData.IsValid())
488 {
489 return ConsoleVariableDataLessThan(*ConsoleVariableData, *Other.ConsoleVariableData);
490 }
491
492 return false; // Both pointers are invalid
493 }
494
495 case ECookDependency::Function:
496 {
497 int32 Compare = FunctionData.Name.Compare(Other.FunctionData.Name);
498 if (Compare != 0)
499 {
500 return Compare < 0;
501 }
504 bool bHasViewA = FunctionData.Args.TryGetRangeView(ViewA);
505 bool bHasViewB = Other.FunctionData.Args.TryGetRangeView(ViewB);
506 if ((!bHasViewA) | (!bHasViewB))
507 {
508 return bHasViewB; // If both false, return false. If only one, return true only if A is the false.
509 }
510 return ViewA.CompareBytes(ViewB) < 0;
511 }
512 case ECookDependency::TransitiveBuild:
513 {
514 // FName.Compare is lexical and case-insensitive, which is what we want
515 int32 Compare = TransitiveBuildData.PackageName.Compare(Other.TransitiveBuildData.PackageName);
516 if (Compare != 0)
517 {
518 return Compare < 0;
519 }
520 return false;
521 }
522 case ECookDependency::Package:
523 return NameData.Compare(Other.NameData) < 0;
524 case ECookDependency::Config:
525 if (ConfigAccessData.IsValid() != Other.ConfigAccessData.IsValid())
526 {
527 return !ConfigAccessData.IsValid();
528 }
529 if (!ConfigAccessData.IsValid())
530 {
531 return false; // equal
532 }
533 return ConfigAccessDataLessThan(*ConfigAccessData, *Other.ConfigAccessData);
534 case ECookDependency::SettingsObject:
535 // SettingsObjects are not persistable, so we do not use a persistent sort key; just the object ptr.
536 return ObjectPtr < Other.ObjectPtr;
537 case ECookDependency::AssetRegistryQuery:
538 if (ARFilter.IsValid() != Other.ARFilter.IsValid())
539 {
540 return !ARFilter.IsValid();
541 }
542 if (!ARFilter.IsValid())
543 {
544 return false; // equal
545 }
546 return ARFilterLessThan(*ARFilter, *Other.ARFilter);
547 case ECookDependency::RedirectionTarget:
548 return NameData.Compare(Other.NameData) < 0;
549 case ECookDependency::Count:
550 default:
551 checkNoEntry();
552 return false;
553 }
554}
555
556inline bool FCookDependency::operator==(const FCookDependency& Other) const
557{
558 if (static_cast<uint8>(Type) != static_cast<uint8>(Other.Type))
559 {
560 return false;
561 }
562
563 switch (Type)
564 {
565 case ECookDependency::None:
566 return true;
567 case ECookDependency::File:
568 case ECookDependency::NativeClass:
569 return StringData.Compare(Other.StringData, ESearchCase::IgnoreCase) == 0;
570
571 case ECookDependency::ConsoleVariable:
572 {
573 if (ConsoleVariableData.IsValid() != Other.ConsoleVariableData.IsValid())
574 {
575 return false;
576 }
577
578 if (!ConsoleVariableData.IsValid())
579 {
580 return true;
581 }
582
583 return ConsoleVariableDataEqual(*ConsoleVariableData, *Other.ConsoleVariableData);
584 }
585
586 case ECookDependency::Function:
587 {
588 if (FunctionData.Name.Compare(Other.FunctionData.Name) != 0)
589 {
590 return false;
591 }
594 bool bHasViewA = FunctionData.Args.TryGetRangeView(ViewA);
595 bool bHasViewB = Other.FunctionData.Args.TryGetRangeView(ViewB);
596 if (bHasViewA != bHasViewB)
597 {
598 return false;
599 }
600 return ViewA.CompareBytes(ViewB) == 0;
601 }
602 case ECookDependency::TransitiveBuild:
603 {
604 // FName.Compare is lexical and case-insensitive, which is what we want
605 int32 Compare = TransitiveBuildData.PackageName.Compare(Other.TransitiveBuildData.PackageName);
606 if (Compare != 0)
607 {
608 return false;
609 }
610 return true;
611 }
612 case ECookDependency::Package:
613 return NameData.Compare(Other.NameData) == 0;
614 case ECookDependency::Config:
615 if (ConfigAccessData.IsValid() != Other.ConfigAccessData.IsValid())
616 {
617 return false;
618 }
619 if (!ConfigAccessData.IsValid())
620 {
621 return true;
622 }
623 return ConfigAccessDataEqual(*ConfigAccessData, *Other.ConfigAccessData);
624 case ECookDependency::SettingsObject:
625 // SettingsObjects are not persistable, so we do not use a persistent sort key; just the object ptr.
626 return ObjectPtr == Other.ObjectPtr;
627 case ECookDependency::AssetRegistryQuery:
628 {
629 if (ARFilter.IsValid() != Other.ARFilter.IsValid())
630 {
631 return false;
632 }
633 if (!ARFilter.IsValid())
634 {
635 return true;
636 }
637
638 return ARFilterEqual(*ARFilter, *Other.ARFilter);
639 }
640 case ECookDependency::RedirectionTarget:
641 return NameData.Compare(Other.NameData) == 0;
642 case ECookDependency::Count:
643 default:
644 checkNoEntry();
645 return false;
646 }
647}
648
649inline bool FCookDependency::operator!=(const FCookDependency& Other) const
650{
651 return !(*this == Other);
652}
653
654inline void FCookDependency::SetValue(const FIoHash& Hash)
655{
656 SetValue(ConvertToHash(Hash));
657}
658
659inline void FCookDependency::SetValue(const FUtf8String& String)
660{
661 SetValue(ConvertToHash(String));
662}
663
664} // namespace UE::Cook
665
666namespace UE::Cook::Dependency::Private
667{
668
669inline FName FCookDependencyFunctionRegistration::GetFName()
670{
671 return Name.Resolve();
672}
673
674} // namespace UE::Cook::Dependency::Private
675
676#endif
OODEFFUNC typedef const int const char * function
Definition oodle2.h:710
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
OODEFFUNC typedef void OO_U64 * dependencies
Definition oodle2.h:588
#define check(expr)
Definition AssertionMacros.h:314
#define checkNoEntry()
Definition AssertionMacros.h:316
bool LoadFromCompactBinary(FCbFieldView Field, FAssetDependency &Dependency)
Definition AssetRegistry.cpp:10420
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
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
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
#define PRAGMA_DISABLE_SWITCH_UNHANDLED_ENUM_CASE_WARNINGS
Definition MSVCPlatformCompilerPreSetup.h:105
#define PRAGMA_RESTORE_SWITCH_UNHANDLED_ENUM_CASE_WARNINGS
Definition MSVCPlatformCompilerPreSetup.h:111
void Construct(const FArguments &InArgs)
TStringView< TCHAR > FStringView
Definition StringFwd.h:45
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition CompactBinary.h:1288
Definition CompactBinary.h:892
Definition CompactBinary.h:610
Definition CompactBinaryWriter.h:68
CORE_API FCbFieldIterator Save() const
Definition CompactBinaryWriter.cpp:98
Definition NameTypes.h:1680
Definition NameTypes.h:617
int32 CompareBytes(const TMemoryView< OtherDataType > &InView) const
Definition MemoryView.h:174
Definition UniquePtr.h:107
Definition Class.h:3793
Definition Object.h:95
Type
Definition PawnAction_Move.h:11
@ IgnoreCase
Definition CString.h:26
Definition ConfigAccessTracking.h:154
Definition CookOnTheFly.h:19
const TCHAR * LexToString(ECookOnTheFlyMessage Message)
Definition CookOnTheFly.h:59
FName GetFName(const UObject *Obj)
Definition ObjectFwd.cpp:13
Definition AdvancedWidgetsModule.cpp:13
@ Config
Property should be loaded/saved to ini file as permanent profile.
Definition ObjectMacros.h:1053
Definition ARFilter.h:23
Definition Blake3.h:27
Definition IoHash.h:33