Working
This commit is contained in:
parent
3f43bdb16b
commit
80ea24a694
2 changed files with 125 additions and 57 deletions
|
@ -8,7 +8,6 @@
|
||||||
#include "GameFramework/GameUserSettings.h"
|
#include "GameFramework/GameUserSettings.h"
|
||||||
|
|
||||||
UHarmonyLinkGraphics* UHarmonyLinkGraphics::_INSTANCE = nullptr;
|
UHarmonyLinkGraphics* UHarmonyLinkGraphics::_INSTANCE = nullptr;
|
||||||
FString UHarmonyLinkGraphics::_IniLocation = "HarmonyLink";
|
|
||||||
int32 UHarmonyLinkGraphics::_TickRate = 1;
|
int32 UHarmonyLinkGraphics::_TickRate = 1;
|
||||||
|
|
||||||
TMap<FName, TMap<FName, FHLConfigValue>> UHarmonyLinkGraphics::_DefaultSettings = {
|
TMap<FName, TMap<FName, FHLConfigValue>> UHarmonyLinkGraphics::_DefaultSettings = {
|
||||||
|
@ -38,6 +37,7 @@ UHarmonyLinkGraphics::UHarmonyLinkGraphics()
|
||||||
|
|
||||||
_bAutomaticSwitch = true;
|
_bAutomaticSwitch = true;
|
||||||
FWorldDelegates::OnPostWorldInitialization.AddUObject(this, &UHarmonyLinkGraphics::OnPostWorldInitialization);
|
FWorldDelegates::OnPostWorldInitialization.AddUObject(this, &UHarmonyLinkGraphics::OnPostWorldInitialization);
|
||||||
|
FWorldDelegates::OnPreWorldFinishDestroy.AddUObject(this, &UHarmonyLinkGraphics::OnWorldEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
UHarmonyLinkGraphics::~UHarmonyLinkGraphics()
|
UHarmonyLinkGraphics::~UHarmonyLinkGraphics()
|
||||||
|
@ -64,7 +64,7 @@ bool UHarmonyLinkGraphics::LoadSettingsFromConfig()
|
||||||
// Load the configuration from the INI file
|
// Load the configuration from the INI file
|
||||||
FConfigFile ConfigFile;
|
FConfigFile ConfigFile;
|
||||||
|
|
||||||
const FString Filename = GetDefaultConfigFilename();
|
const FString Filename = GetConfigDirectoryFile();
|
||||||
|
|
||||||
if (!GConfig)
|
if (!GConfig)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +158,7 @@ void UHarmonyLinkGraphics::SaveConfig() const
|
||||||
SaveSection(Profile.Value);
|
SaveSection(Profile.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FString Filename = GetDefaultConfigFilename();
|
const FString Filename = GetConfigDirectoryFile();
|
||||||
UE_LOG(LogHarmonyLink, Log, TEXT("Flushing file: '%s'"), *Filename);
|
UE_LOG(LogHarmonyLink, Log, TEXT("Flushing file: '%s'"), *Filename);
|
||||||
GConfig->Flush(false, Filename);
|
GConfig->Flush(false, Filename);
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,9 @@ void UHarmonyLinkGraphics::DestroySettings()
|
||||||
{
|
{
|
||||||
if (_INSTANCE)
|
if (_INSTANCE)
|
||||||
{
|
{
|
||||||
|
UE_LOG(LogHarmonyLink, Log, TEXT("Destroying UHarmonyLinkGraphics."))
|
||||||
FWorldDelegates::OnPostWorldInitialization.RemoveAll(_INSTANCE);
|
FWorldDelegates::OnPostWorldInitialization.RemoveAll(_INSTANCE);
|
||||||
|
FWorldDelegates::OnPreWorldFinishDestroy.RemoveAll(_INSTANCE);
|
||||||
_INSTANCE->RemoveFromRoot();
|
_INSTANCE->RemoveFromRoot();
|
||||||
_INSTANCE->MarkAsGarbage();
|
_INSTANCE->MarkAsGarbage();
|
||||||
_INSTANCE = nullptr;
|
_INSTANCE = nullptr;
|
||||||
|
@ -290,36 +292,54 @@ void UHarmonyLinkGraphics::Init()
|
||||||
// BUG: Remove this before release!
|
// BUG: Remove this before release!
|
||||||
if (!BatteryStatus.HasBattery)
|
if (!BatteryStatus.HasBattery)
|
||||||
{
|
{
|
||||||
ApplyProfile(EProfile::BATTERY);
|
ApplyProfileInternal(EProfile::BATTERY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UHarmonyLinkGraphics::Tick()
|
void UHarmonyLinkGraphics::Tick()
|
||||||
{
|
{
|
||||||
if (!_bAutomaticSwitch)
|
Async(EAsyncExecution::Thread, [this]()
|
||||||
{
|
{
|
||||||
return;
|
const FBattery BatteryStatus = UHarmonyLinkLibrary::GetBatteryStatus();
|
||||||
}
|
|
||||||
|
|
||||||
const FBattery BatteryStatus = UHarmonyLinkLibrary::GetBatteryStatus();
|
if (BatteryStatus.BatteryPercent != _LastBatteryPercentage)
|
||||||
|
|
||||||
if (BatteryStatus.HasBattery)
|
|
||||||
{
|
|
||||||
if (BatteryStatus.IsACConnected)
|
|
||||||
{
|
{
|
||||||
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()
|
void UHarmonyLinkGraphics::CreateDefaultConfigFile()
|
||||||
|
@ -332,11 +352,22 @@ void UHarmonyLinkGraphics::CreateDefaultConfigFile()
|
||||||
UE_LOG(LogHarmonyLink, Log, TEXT("Default config file created."));
|
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)
|
if (GConfig)
|
||||||
{
|
{
|
||||||
const FString Filename = GetDefaultConfigFilename();
|
const FString Filename = GetConfigDirectoryFile();
|
||||||
for (const auto& Setting : SettingsProfile.Settings)
|
for (const auto& Setting : SettingsProfile.Settings)
|
||||||
{
|
{
|
||||||
FString TypeString;
|
FString TypeString;
|
||||||
|
@ -396,35 +427,7 @@ void UHarmonyLinkGraphics::LoadDefaults()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UHarmonyLinkGraphics::OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS)
|
bool UHarmonyLinkGraphics::ApplyProfileInternal(const EProfile Profile)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
// If the profile is None, revert to the original user game settings
|
// If the profile is None, revert to the original user game settings
|
||||||
if (Profile == EProfile::NONE)
|
if (Profile == EProfile::NONE)
|
||||||
|
@ -485,6 +488,62 @@ bool UHarmonyLinkGraphics::ApplyProfile(const EProfile Profile)
|
||||||
return true;
|
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)
|
void UHarmonyLinkGraphics::ApplySetting(const TPair<FName, FHLConfigValue>& Setting)
|
||||||
{
|
{
|
||||||
// Apply the setting based on the key (CVar)
|
// Apply the setting based on the key (CVar)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProfileChanged, EProfile, Profile);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProfileChanged, EProfile, Profile);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAutomaticSwitchChanged, bool, bAutomaticSwich);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAutomaticSwitchChanged, bool, bAutomaticSwich);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnBatteryLevelChanged, int32, BatteryPercent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -29,6 +30,9 @@ public:
|
||||||
|
|
||||||
UPROPERTY(BlueprintAssignable)
|
UPROPERTY(BlueprintAssignable)
|
||||||
FOnAutomaticSwitchChanged OnAutomaticSwitchChanged;
|
FOnAutomaticSwitchChanged OnAutomaticSwitchChanged;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FOnBatteryLevelChanged OnBatteryLevelChanged;
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||||
void LoadConfig(const bool bForceReload = false);
|
void LoadConfig(const bool bForceReload = false);
|
||||||
|
@ -40,7 +44,7 @@ public:
|
||||||
void SetSetting(EProfile Profile, FName Setting, FHLConfigValue Value);
|
void SetSetting(EProfile Profile, FName Setting, FHLConfigValue Value);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
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...) */
|
/** Returns the game local machine settings (resolution, windowing mode, scalability settings, etc...) */
|
||||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||||
|
@ -64,25 +68,30 @@ private:
|
||||||
void Init();
|
void Init();
|
||||||
void Tick();
|
void Tick();
|
||||||
void CreateDefaultConfigFile();
|
void CreateDefaultConfigFile();
|
||||||
|
static FString GetConfigDirectoryFile();
|
||||||
bool LoadSettingsFromConfig();
|
bool LoadSettingsFromConfig();
|
||||||
bool LoadSection(const FConfigFile& ConfigFile, const TPair<EProfile, FName> Profile);
|
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();
|
void LoadDefaults();
|
||||||
|
bool ApplyProfileInternal(EProfile Profile);
|
||||||
|
|
||||||
|
|
||||||
void OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS);
|
void OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS);
|
||||||
|
void OnWorldEnd(UWorld* World);
|
||||||
|
|
||||||
static void ResetInstance();
|
static void ResetInstance();
|
||||||
|
|
||||||
|
// Note: Turning off HarmonyLink Settings requires game restart
|
||||||
static void ApplySetting(const TPair<FName, FHLConfigValue>& Setting);
|
static void ApplySetting(const TPair<FName, FHLConfigValue>& Setting);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
void DebugPrintProfiles() const;
|
void DebugPrintProfiles() const;
|
||||||
static void PrintDebugSection(FSettingsProfile& SettingsProfile);
|
static void PrintDebugSection(FSettingsProfile& SettingsProfile);
|
||||||
|
|
||||||
static FString _IniLocation;
|
|
||||||
|
|
||||||
uint8 _bAutomaticSwitch :1;
|
uint8 _bAutomaticSwitch :1;
|
||||||
|
|
||||||
|
int32 _LastBatteryPercentage = 0;
|
||||||
|
|
||||||
// How many times to query HarmonyLinkLib for hardware info
|
// How many times to query HarmonyLinkLib for hardware info
|
||||||
static int32 _TickRate;
|
static int32 _TickRate;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue