UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
FontCacheUtils.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Stats/Stats.h"
7#include "SlateGlobals.h"
8
10
15{
16public:
18 : LookupSet()
19 , MostRecent(nullptr)
20 , LeastRecent(nullptr)
21 , MaxNumElements(InMaxNumElements)
22 { }
23
25 {
26 Empty();
27 }
28
33 {
34 FCacheEntry** Entry = LookupSet.FindByHash(FLookupSet::KeyFuncsType::GetKeyHash(Key), Key);
35 if( Entry )
36 {
37 MarkAsRecent( *Entry );
38 return &((*Entry)->Value);
39 }
40
41 return nullptr;
42 }
43
44 void Add( FStringView Key, const FVector2f& Value )
45 {
46 FCacheEntry** Entry = LookupSet.FindByHash(FLookupSet::KeyFuncsType::GetKeyHash(Key), Key);
47
48 // Make a new link
49 if( !Entry )
50 {
51 if( LookupSet.Num() == MaxNumElements )
52 {
53 Eject();
54 checkf( LookupSet.Num() < MaxNumElements, TEXT("Could not eject item from the LRU: (%d of %d), %s"), LookupSet.Num(), MaxNumElements, LeastRecent ? *LeastRecent->Key : TEXT("NULL"));
55 }
56
57 FCacheEntry* NewEntry = new FCacheEntry( FString(Key), Value );
58
59 // Link before the most recent so that we become the most recent
60 NewEntry->Link(MostRecent);
61 MostRecent = NewEntry;
62
63 if( LeastRecent == nullptr )
64 {
65 LeastRecent = NewEntry;
66 }
67
68 STAT( uint32 CurrentMemUsage = LookupSet.GetAllocatedSize() );
69 LookupSet.Add( NewEntry );
70 STAT( uint32 NewMemUsage = LookupSet.GetAllocatedSize() );
72 }
73 else
74 {
75 // Trying to add an existing value
76 FCacheEntry* EntryPtr = *Entry;
77
78 // Update the value
79 EntryPtr->Value = Value;
80 checkSlow(FLookupSet::KeyFuncsType::Matches(EntryPtr->Key, Key));
81 // Mark as the most recent
82 MarkAsRecent( EntryPtr );
83 }
84 }
85
86 void Empty()
87 {
88 DEC_MEMORY_STAT_BY( STAT_SlateFontMeasureCacheMemory, LookupSet.GetAllocatedSize() );
89
90 for( TSet<FCacheEntry*, FCaseSensitiveStringKeyFuncs >::TIterator It(LookupSet); It; ++It )
91 {
92 FCacheEntry* Entry = *It;
93 // Note no need to unlink anything here. we are emptying the entire list
94 delete Entry;
95 }
96 LookupSet.Empty();
97
98 MostRecent = LeastRecent = nullptr;
99 }
100private:
101 struct FCacheEntry
102 {
103 FString Key;
104 FVector2f Value;
105 FCacheEntry* Next;
106 FCacheEntry* Prev;
107
108 FCacheEntry( FString InKey, const FVector2f& InValue )
109 : Key( MoveTemp(InKey) )
110 , Value( InValue )
111 , Next( nullptr )
112 , Prev( nullptr )
113 {
114 INC_MEMORY_STAT_BY( STAT_SlateFontMeasureCacheMemory, Key.GetAllocatedSize()+sizeof(Value)+sizeof(Next)+sizeof(Prev) );
115 }
116
117 ~FCacheEntry()
118 {
119 DEC_MEMORY_STAT_BY( STAT_SlateFontMeasureCacheMemory, Key.GetAllocatedSize()+sizeof(Value)+sizeof(Next)+sizeof(Prev) );
120 }
121
122 FORCEINLINE void Link( FCacheEntry* Before )
123 {
124 Next = Before;
125
126 if( Before )
127 {
128 Before->Prev = this;
129 }
130 }
131
132 FORCEINLINE void Unlink()
133 {
134 if( Prev )
135 {
136 Prev->Next = Next;
137 }
138
139 if( Next )
140 {
141 Next->Prev = Prev;
142 }
143
144 Prev = nullptr;
145 Next = nullptr;
146 }
147 };
148
149 struct FCaseSensitiveStringKeyFuncs : BaseKeyFuncs<FCacheEntry*, FString>
150 {
151 FORCEINLINE static const FString& GetSetKey( const FCacheEntry* Entry )
152 {
153 return Entry->Key;
154 }
155
156 FORCEINLINE static bool Matches(const FString& A, const FStringView& B)
157 {
159 }
160
161 FORCEINLINE static uint32 GetKeyHash(FStringView Identifier)
162 {
163 return CityHash32(reinterpret_cast<const char*>(Identifier.GetData()), Identifier.Len() * sizeof(TCHAR));
164 }
165 };
166
167
173 FORCEINLINE void MarkAsRecent( FCacheEntry* Entry )
174 {
175 checkSlow( LeastRecent && MostRecent );
176
177 // If we are the least recent entry we are no longer the least recent
178 // The previous least recent item is now the most recent. If it is nullptr then this entry is the only item in the list
179 if( Entry == LeastRecent && LeastRecent->Prev != nullptr )
180 {
181 LeastRecent = LeastRecent->Prev;
182 }
183
184 // No need to relink if we happen to already be accessing the most recent value
185 if( Entry != MostRecent )
186 {
187 // Unlink from its current spot
188 Entry->Unlink();
189
190 // Relink before the most recent so that we become the most recent
191 Entry->Link(MostRecent);
192 MostRecent = Entry;
193 }
194 }
195
199 FORCEINLINE void Eject()
200 {
201 FCacheEntry* EntryToRemove = LeastRecent;
202 // Eject the least recent, no more space
204 STAT( uint32 CurrentMemUsage = LookupSet.GetAllocatedSize() );
205 LookupSet.Remove( EntryToRemove->Key );
206 STAT( uint32 NewMemUsage = LookupSet.GetAllocatedSize() );
208
209 LeastRecent = LeastRecent->Prev;
210
211 // Unlink the LRU
212 EntryToRemove->Unlink();
213
214 delete EntryToRemove;
215 }
216
217private:
219 FLookupSet LookupSet;
221 FCacheEntry* MostRecent;
223 FCacheEntry* LeastRecent;
225 int32 MaxNumElements;
226};
227
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
uint32 CityHash32(const char *s, uint32 len)
Definition CityHash.cpp:203
#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 INC_MEMORY_STAT_BY(StatId, Amount)
Definition Stats.h:700
#define DEC_MEMORY_STAT_BY(StatId, Amount)
Definition Stats.h:705
#define STAT(x)
Definition Stats.h:44
#define DECLARE_MEMORY_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:687
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
TStringView< TCHAR > FStringView
Definition StringFwd.h:45
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition FontCacheUtils.h:15
void Empty()
Definition FontCacheUtils.h:86
~FLRUStringCache()
Definition FontCacheUtils.h:24
FORCEINLINE const FVector2f * AccessItem(FStringView Key)
Definition FontCacheUtils.h:32
void Add(FStringView Key, const FVector2f &Value)
Definition FontCacheUtils.h:44
FLRUStringCache(int32 InMaxNumElements)
Definition FontCacheUtils.h:17
bool Equals(TStringView< OtherCharType > OtherView, ESearchCase::Type SearchCase=ESearchCase::CaseSensitive) const
Definition StringView.h:306
@ CaseSensitive
Definition CString.h:23
VERSECOMPILER_API bool Matches(const CTypeBase *PositiveType1, const CTypeBase *NegativeType2, const uint32_t UploadedAtFnVersion)
Determine if argument PositiveType1 is a match for parameter NegativeType2
Definition SemanticTypes.cpp:2971
Definition SetUtilities.h:23