This commit is contained in:
Jordon Brooks 2024-05-16 01:39:54 +01:00
parent 3f43bdb16b
commit 80ea24a694
Signed by: jordon
GPG key ID: DBD9758CD53E786A
2 changed files with 125 additions and 57 deletions

View file

@ -8,7 +8,6 @@
#include "GameFramework/GameUserSettings.h"
UHarmonyLinkGraphics* UHarmonyLinkGraphics::_INSTANCE = nullptr;
FString UHarmonyLinkGraphics::_IniLocation = "HarmonyLink";
int32 UHarmonyLinkGraphics::_TickRate = 1;
TMap<FName, TMap<FName, FHLConfigValue>> UHarmonyLinkGraphics::_DefaultSettings = {
@ -38,6 +37,7 @@ UHarmonyLinkGraphics::UHarmonyLinkGraphics()
_bAutomaticSwitch = true;
FWorldDelegates::OnPostWorldInitialization.AddUObject(this, &UHarmonyLinkGraphics::OnPostWorldInitialization);
FWorldDelegates::OnPreWorldFinishDestroy.AddUObject(this, &UHarmonyLinkGraphics::OnWorldEnd);
}
UHarmonyLinkGraphics::~UHarmonyLinkGraphics()
@ -64,7 +64,7 @@ bool UHarmonyLinkGraphics::LoadSettingsFromConfig()
// Load the configuration from the INI file
FConfigFile ConfigFile;
const FString Filename = GetDefaultConfigFilename();
const FString Filename = GetConfigDirectoryFile();
if (!GConfig)
{
@ -158,7 +158,7 @@ void UHarmonyLinkGraphics::SaveConfig() const
SaveSection(Profile.Value);
}
const FString Filename = GetDefaultConfigFilename();
const FString Filename = GetConfigDirectoryFile();
UE_LOG(LogHarmonyLink, Log, TEXT("Flushing file: '%s'"), *Filename);
GConfig->Flush(false, Filename);
}
@ -272,7 +272,9 @@ void UHarmonyLinkGraphics::DestroySettings()
{
if (_INSTANCE)
{
UE_LOG(LogHarmonyLink, Log, TEXT("Destroying UHarmonyLinkGraphics."))
FWorldDelegates::OnPostWorldInitialization.RemoveAll(_INSTANCE);
FWorldDelegates::OnPreWorldFinishDestroy.RemoveAll(_INSTANCE);
_INSTANCE->RemoveFromRoot();
_INSTANCE->MarkAsGarbage();
_INSTANCE = nullptr;
@ -290,36 +292,54 @@ void UHarmonyLinkGraphics::Init()
// BUG: Remove this before release!
if (!BatteryStatus.HasBattery)
{
ApplyProfile(EProfile::BATTERY);
ApplyProfileInternal(EProfile::BATTERY);
}
}
void UHarmonyLinkGraphics::Tick()
{
if (!_bAutomaticSwitch)
Async(EAsyncExecution::Thread, [this]()
{
return;
}
const FBattery BatteryStatus = UHarmonyLinkLibrary::GetBatteryStatus();
const FBattery BatteryStatus = UHarmonyLinkLibrary::GetBatteryStatus();
if (BatteryStatus.HasBattery)
{
if (BatteryStatus.IsACConnected)
if (BatteryStatus.BatteryPercent != _LastBatteryPercentage)
{
if (_ActiveProfile != EProfile::CHARGING)
// Ensure thread-safe broadcasting
Async(EAsyncExecution::TaskGraphMainThread, [this, BatteryStatus]()
{
ApplyProfile(EProfile::CHARGING);
OnBatteryLevelChanged.Broadcast(BatteryStatus.BatteryPercent);
});
}
if (!_bAutomaticSwitch)
{
return;
}
if (BatteryStatus.HasBattery)
{
if (BatteryStatus.IsACConnected)
{
if (_ActiveProfile != EProfile::CHARGING)
{
Async(EAsyncExecution::TaskGraphMainThread, [this]()
{
ApplyProfileInternal(EProfile::CHARGING);
});
}
}
else
{
if (_ActiveProfile != EProfile::BATTERY)
{
Async(EAsyncExecution::TaskGraphMainThread, [this]()
{
ApplyProfileInternal(EProfile::BATTERY);
});
}
}
}
else
{
if (_ActiveProfile != EProfile::BATTERY)
{
ApplyProfile(EProfile::BATTERY);
}
}
}
});
}
void UHarmonyLinkGraphics::CreateDefaultConfigFile()
@ -332,11 +352,22 @@ void UHarmonyLinkGraphics::CreateDefaultConfigFile()
UE_LOG(LogHarmonyLink, Log, TEXT("Default config file created."));
}
void UHarmonyLinkGraphics::SaveSection(FSettingsProfile& SettingsProfile, const bool bFlush) const
FString UHarmonyLinkGraphics::GetConfigDirectoryFile()
{
FString ConfigFileName = "HarmonyLink.ini"; // Replace with your actual config file name
#if WITH_EDITOR
return FPaths::Combine(FPaths::ProjectSavedDir(), TEXT("Config"), ConfigFileName);
#else
return FPaths::Combine(FPaths::ProjectConfigDir(), ConfigFileName);
#endif
}
void UHarmonyLinkGraphics::SaveSection(FSettingsProfile& SettingsProfile, const bool bFlush)
{
if (GConfig)
{
const FString Filename = GetDefaultConfigFilename();
const FString Filename = GetConfigDirectoryFile();
for (const auto& Setting : SettingsProfile.Settings)
{
FString TypeString;
@ -396,35 +427,7 @@ void UHarmonyLinkGraphics::LoadDefaults()
}
}
void UHarmonyLinkGraphics::OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS)
{
if (!World)
{
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to Hook into World Initialisation!"))
return;
}
if (World->IsGameWorld())
{
if (UHarmonyLinkGraphics* Settings = GetSettings())
{
if (World->IsPlayInEditor())
{
Settings->LoadConfig(true);
}
if (!World->GetTimerManager().TimerExists(Settings->_TickTimerHandle) || !World->GetTimerManager().IsTimerActive(Settings->_TickTimerHandle))
{
World->GetTimerManager().SetTimer(Settings->_TickTimerHandle, [Settings]
{
Settings->Tick();
}, _TickRate, true);
}
}
}
}
bool UHarmonyLinkGraphics::ApplyProfile(const EProfile Profile)
bool UHarmonyLinkGraphics::ApplyProfileInternal(const EProfile Profile)
{
// If the profile is None, revert to the original user game settings
if (Profile == EProfile::NONE)
@ -485,6 +488,62 @@ bool UHarmonyLinkGraphics::ApplyProfile(const EProfile Profile)
return true;
}
void UHarmonyLinkGraphics::OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS)
{
if (!World)
{
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to Hook into World Initialisation!"))
return;
}
if (World->IsGameWorld())
{
if (UHarmonyLinkGraphics* Settings = GetSettings())
{
if (World->IsPlayInEditor())
{
Settings->LoadConfig(true);
}
if (!World->GetTimerManager().TimerExists(Settings->_TickTimerHandle) || !World->GetTimerManager().IsTimerActive(Settings->_TickTimerHandle))
{
World->GetTimerManager().SetTimer(Settings->_TickTimerHandle, [Settings]
{
Settings->Tick();
}, _TickRate, true);
}
}
}
}
void UHarmonyLinkGraphics::OnWorldEnd(UWorld* World)
{
if (!World)
{
UE_LOG(LogHarmonyLink, Error, TEXT("World Already destroyed"))
return;
}
if(World->GetTimerManager().TimerExists(_TickTimerHandle))
{
World->GetTimerManager().ClearTimer(_TickTimerHandle);
}
// Ensure we safely destroy our singleton instance
DestroySettings();
}
bool UHarmonyLinkGraphics::ApplyProfile(const EProfile Profile, const bool bDisableAuto)
{
// Manual profile change, turn off automatic switching
if (bDisableAuto)
{
_bAutomaticSwitch = false;
}
return ApplyProfileInternal(Profile);
}
void UHarmonyLinkGraphics::ApplySetting(const TPair<FName, FHLConfigValue>& Setting)
{
// Apply the setting based on the key (CVar)

View file

@ -11,6 +11,7 @@
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProfileChanged, EProfile, Profile);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAutomaticSwitchChanged, bool, bAutomaticSwich);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnBatteryLevelChanged, int32, BatteryPercent);
/**
*
@ -30,6 +31,9 @@ public:
UPROPERTY(BlueprintAssignable)
FOnAutomaticSwitchChanged OnAutomaticSwitchChanged;
UPROPERTY(BlueprintAssignable)
FOnBatteryLevelChanged OnBatteryLevelChanged;
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
void LoadConfig(const bool bForceReload = false);
@ -40,7 +44,7 @@ public:
void SetSetting(EProfile Profile, FName Setting, FHLConfigValue Value);
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
bool ApplyProfile(EProfile Profile);
bool ApplyProfile(EProfile Profile, const bool bDisableAuto = true);
/** Returns the game local machine settings (resolution, windowing mode, scalability settings, etc...) */
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
@ -64,25 +68,30 @@ private:
void Init();
void Tick();
void CreateDefaultConfigFile();
static FString GetConfigDirectoryFile();
bool LoadSettingsFromConfig();
bool LoadSection(const FConfigFile& ConfigFile, const TPair<EProfile, FName> Profile);
void SaveSection(FSettingsProfile& SettingsProfile, const bool bFlush = false) const;
static void SaveSection(FSettingsProfile& SettingsProfile, const bool bFlush = false);
void LoadDefaults();
bool ApplyProfileInternal(EProfile Profile);
void OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS);
void OnWorldEnd(UWorld* World);
static void ResetInstance();
// Note: Turning off HarmonyLink Settings requires game restart
static void ApplySetting(const TPair<FName, FHLConfigValue>& Setting);
// Debugging
void DebugPrintProfiles() const;
static void PrintDebugSection(FSettingsProfile& SettingsProfile);
static FString _IniLocation;
uint8 _bAutomaticSwitch :1;
int32 _LastBatteryPercentage = 0;
// How many times to query HarmonyLinkLib for hardware info
static int32 _TickRate;