Live Config
Loading...
Searching...
No Matches
LiveConfigSystem.h
1// Copyright (c) 2026 Nicholas Arthur
2// Licensed under the MIT License
3
4#pragma once
5
6#include "UObject/UnrealType.h"
7#include "Subsystems/EngineSubsystem.h"
8#include "Interfaces/IHttpRequest.h"
9#include "CoreMinimal.h"
10#include "LiveConfigTypes.h"
11#include "LiveConfigPropertyName.h"
12#include "Profiles/LiveConfigProfile.h"
13#include "ConsoleSettings.h"
14#include "LiveConfigSystem.generated.h"
15
16DECLARE_MULTICAST_DELEGATE(FOnLiveConfigPropertiesUpdated);
17DECLARE_MULTICAST_DELEGATE_OneParam(FOnRemoteSyncDetected, const TArray<FLiveConfigPropertyDefinition>&);
18
19namespace LiveConfigTags
20{
21 const LIVECONFIG_API extern FName FromCurveTable;
22}
23
28UCLASS(BlueprintType, Config=Game, DefaultConfig)
29class LIVECONFIG_API ULiveConfigSystem : public UEngineSubsystem
30{
31 GENERATED_BODY()
32
33public:
34 FOnLiveConfigPropertiesUpdated OnPropertiesUpdated;
35
36 FSimpleMulticastDelegate OnTagsChanged;
37
41 FSimpleMulticastDelegate OnRemoteOverridesLoaded;
42
44 FOnRemoteSyncDetected OnDataProviderSync;
45
51 static ULiveConfigSystem& Get();
52
53 // USubsystem
54 virtual void Initialize(FSubsystemCollectionBase& Collection) override;
55 virtual void Deinitialize() override;
56 virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
57 // ~USubsystem
58
62 void SaveProperty(const FLiveConfigPropertyDefinition& PropertyDefinition);
63
69 bool UpdateStructProperties(const FLiveConfigPropertyDefinition& PropertyDefinition);
70
74 void SavePropertyDeferred(const FLiveConfigPropertyDefinition& PropertyDefinition);
75
83 void RenameProperty(FLiveConfigProperty OldName, FLiveConfigProperty NewName, bool bCreateRedirector = false);
84
85 void DeleteProperty(FLiveConfigProperty Property);
86
92 FString GetStringValue(FLiveConfigProperty Key) const;
93
95 float GetFloatValue(FLiveConfigProperty Key) const;
96
98 int32 GetIntValue(FLiveConfigProperty Key) const;
99
101 bool GetBoolValue(FLiveConfigProperty Key) const;
102
107 template<typename T>
109 {
110 T OutStruct;
111 UScriptStruct* Struct = TBaseStructure<T>::Get();
112 if (!Struct)
113 {
114 Struct = T::StaticStruct();
115 }
116 GetLiveConfigStruct_Internal(Struct, &OutStruct, StructProperty);
117 return OutStruct;
118 }
119
124 template<typename T>
126 {
127 RedirectPropertyName(Property);
128 return Cache.GetValue<T>(Property);
129 }
130
131 void GetLiveConfigStruct_Internal(class UScriptStruct* Struct, void* OutStructPtr, FLiveConfigProperty Prefix) const;
132
133 void GetStructPropertyMembers(FLiveConfigProperty StructProperty, TArray<FLiveConfigProperty>& OutProperties);
134
140 void GetSubProperties(FName PropertyPath, TArray<FLiveConfigProperty>& OutProperties);
141
143 UFUNCTION(BlueprintCallable, Category = "Live Config")
144 bool IsDataReady() const { return bIsDataReady; }
145
149 UFUNCTION(BlueprintCallable, Category = "Live Config")
150 void PatchEnvironmentOverrides(const FLiveConfigProfile& InProfile);
151
156 void SyncRemoteToLocal();
157
161 TArray<FLiveConfigPropertyDefinition> GetProfileDiff(const FLiveConfigProfile& Profile);
162
167 const TArray<FLiveConfigPropertyDefinition>& SaveProperties(const TArray<FLiveConfigPropertyDefinition>& Properties);
168 FString GetDiffString(const TArray<FLiveConfigPropertyDefinition>& Diff);
169
174 FText GetDiffText(const TArray<FLiveConfigPropertyDefinition>& Diff);
175
176
177 void DownloadConfig();
178
180 void RebuildConfigCache();
181 void RebuildConfigCache(const FLiveConfigProfile& Profile);
182
184 UFUNCTION(BlueprintCallable, Category = "Live Config")
185 const TMap<FLiveConfigProperty, FLiveConfigPropertyDefinition>& GetAllProperties() const;
186
187 static bool DoesPropertyNameExist(FLiveConfigProperty PropertyName);
188
190 void RedirectPropertyName(FLiveConfigProperty& Property) const;
191
195 static void GetActiveSource(ELiveConfigSourceType& OutSourceType, FString& OutSourcePath);
196
201 void RemoveRedirect(FName OldPropertyName);
202
203 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "General")
204 TMap<FLiveConfigProperty, FLiveConfigPropertyDefinition> PropertyDefinitions;
205
206 UPROPERTY(Config, VisibleAnywhere, BlueprintReadOnly, Category = "General")
207 TArray<FName> PropertyTags;
208
209 void HandleTagsChanged();
210
211
212 UPROPERTY(Config)
213 TMap<FName, FName> PropertyRedirects;
214
215
216private:
217 double TimeLoadStarted = -9999;
218 float RateLimitSeconds = 5;
219 FTimerHandle PollingTimer;
220 FTSTicker::FDelegateHandle TimeoutTimer;
221
222 UPROPERTY()
223 FLiveConfigCache Cache;
224
225 // Environment config is treated as a layer below more specific profiles
226 FLiveConfigProfile EnvironmentOverrides;
227
228 float TimeoutDuration;
229
230 void OnTravel(UWorld* World, FWorldInitializationValues WorldInitializationValues);
231 void OnStartGameInstance(UGameInstance* GameInstance);
232
236 UFUNCTION()
237 void BuildCache();
238
239 void PopulateAutoCompleteEntries(TArray<FAutoCompleteCommand>& AutoCompleteCommands);
240
247 void FetchOverrides(ELiveConfigSourceType SourceType, const FString& SourcePath, const FOnRemoteOverridesFetched& OnComplete);
248
250 void FetchProfileCommand(const TArray<FString>& Args);
251
253 bool bIsDataReady = false;
254};
Definition LiveConfigSystem.h:30
FOnRemoteSyncDetected OnDataProviderSync
Definition LiveConfigSystem.h:44
FSimpleMulticastDelegate OnRemoteOverridesLoaded
Definition LiveConfigSystem.h:41
T GetLiveConfigStruct(FLiveConfigProperty StructProperty) const
Definition LiveConfigSystem.h:108
T GetLiveConfigValue(FLiveConfigProperty Property) const
Definition LiveConfigSystem.h:125
Definition LiveConfigTypes.h:86
Definition LiveConfigProfile.h:24
Definition LiveConfigTypes.h:58
Definition LiveConfigPropertyName.h:14