Working profiles & Updated HarmonyLinkLib
This commit is contained in:
parent
3f435a284f
commit
15a2622991
12 changed files with 538 additions and 94 deletions
|
@ -52,23 +52,22 @@ public class HarmonyLink : ModuleRules
|
|||
}
|
||||
);
|
||||
|
||||
// Platform-specific settings
|
||||
if (Target.Platform == UnrealTargetPlatform.Win64)
|
||||
{
|
||||
PublicAdditionalLibraries.Add(Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/bin/Win64/HarmonyLinkLib.lib"));
|
||||
RuntimeDependencies.Add("$(BinaryOutputDir)/HarmonyLinkLib.dll", Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/bin/Win64/HarmonyLinkLib.dll"));
|
||||
}
|
||||
else if (Target.Platform == UnrealTargetPlatform.Linux)
|
||||
{
|
||||
PublicAdditionalLibraries.Add(Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/bin/Linux/libHarmonyLinkLib.so"));
|
||||
RuntimeDependencies.Add("$(BinaryOutputDir)/libHarmonyLinkLib.so", Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/bin/Linux/libHarmonyLinkLib.so"));
|
||||
}
|
||||
|
||||
// Platform-specific settings for static libraries
|
||||
if (Target.Platform == UnrealTargetPlatform.Win64)
|
||||
{
|
||||
PublicAdditionalLibraries.Add(Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/lib/Win64/HarmonyLinkLibStatic.lib"));
|
||||
PublicDefinitions.Add("HARMONYLINKLIB_STATIC=1");
|
||||
}
|
||||
else if (Target.Platform == UnrealTargetPlatform.Linux)
|
||||
{
|
||||
PublicAdditionalLibraries.Add(Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/lib/Linux/libHarmonyLinkLibStatic.a"));
|
||||
PublicDefinitions.Add("HARMONYLINKLIB_STATIC=1");
|
||||
}
|
||||
// I shall include this if anyone wishes to provide Mac binaries of HarmonyLink but these are not included by default as I don't own one.
|
||||
else if (Target.Platform == UnrealTargetPlatform.Mac)
|
||||
{
|
||||
PublicAdditionalLibraries.Add(Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/bin/Mac/HarmonyLinkLib.dylib"));
|
||||
RuntimeDependencies.Add("$(BinaryOutputDir)/HarmonyLinkLib.dylib", Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/bin/Mac/HarmonyLinkLib.dylib"));
|
||||
}
|
||||
else if (Target.Platform == UnrealTargetPlatform.Mac)
|
||||
{
|
||||
PublicAdditionalLibraries.Add(Path.Combine(PluginDirectory, "Source/ThirdParty/HarmonyLinkLib/lib/Mac/libHarmonyLinkLibStatic.a"));
|
||||
PublicDefinitions.Add("HARMONYLINKLIB_STATIC=1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,7 @@ bool UHarmonyLinkLibrary::IsWine()
|
|||
|
||||
bool UHarmonyLinkLibrary::IsLinux()
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
return IsWine();
|
||||
#elif PLATFORM_LINUX
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return HarmonyLinkLib::get_is_linux();
|
||||
}
|
||||
|
||||
bool UHarmonyLinkLibrary::IsSteamDeck()
|
||||
|
|
|
@ -9,7 +9,20 @@
|
|||
|
||||
UHarmonyLinkGraphics* UHarmonyLinkGraphics::_INSTANCE = nullptr;
|
||||
int32 UHarmonyLinkGraphics::_TickRate = 1;
|
||||
FTimerHandle UHarmonyLinkGraphics::_TickTimerHandle = FTimerHandle();
|
||||
|
||||
/**
|
||||
* @brief Default graphics settings for different power states in HarmonyLink.
|
||||
*
|
||||
* This map defines the default configuration values for various graphics settings based on the power state of the device.
|
||||
* The outer map's key is the power state (e.g., "Battery", "Charging", "Docked").
|
||||
* The inner map contains key-value pairs where the key is the setting name and the value is the corresponding configuration value.
|
||||
*
|
||||
* Power States:
|
||||
* - "Battery": Settings for when the device is running on battery power.
|
||||
* - "Charging": Settings for when the device is charging.
|
||||
* - "Docked": Settings for when the device is docked.
|
||||
*/
|
||||
TMap<FName, TMap<FName, FHLConfigValue>> UHarmonyLinkGraphics::_DefaultSettings = {
|
||||
{ "Battery", {
|
||||
{ TEXT("r.ReflectionMethod"), FHLConfigValue(0) },
|
||||
|
@ -34,8 +47,7 @@ TMap<FName, TMap<FName, FHLConfigValue>> UHarmonyLinkGraphics::_DefaultSettings
|
|||
UHarmonyLinkGraphics::UHarmonyLinkGraphics()
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Warning, TEXT("HarmonyLinkGraphics initialized."));
|
||||
|
||||
_bAutomaticSwitch = true;
|
||||
|
||||
FWorldDelegates::OnPostWorldInitialization.AddUObject(this, &UHarmonyLinkGraphics::OnPostWorldInitialization);
|
||||
FWorldDelegates::OnPreWorldFinishDestroy.AddUObject(this, &UHarmonyLinkGraphics::OnWorldEnd);
|
||||
}
|
||||
|
@ -50,25 +62,29 @@ void UHarmonyLinkGraphics::LoadConfig(const bool bForceReload)
|
|||
QUICK_SCOPE_CYCLE_COUNTER(HarmonyLinkGraphics_LoadSettings);
|
||||
|
||||
// Load the settings into the map
|
||||
if (!LoadSettingsFromConfig())
|
||||
if (!LoadSettingsFromConfig(false))
|
||||
{
|
||||
// Retry 2nd time
|
||||
LoadSettingsFromConfig();
|
||||
if (!LoadSettingsFromConfig(true))
|
||||
{
|
||||
CreateDefaultConfigFile();
|
||||
// Retry 2nd time
|
||||
LoadSettingsFromConfig(true);
|
||||
}
|
||||
}
|
||||
|
||||
DebugPrintProfiles();
|
||||
}
|
||||
|
||||
bool UHarmonyLinkGraphics::LoadSettingsFromConfig()
|
||||
bool UHarmonyLinkGraphics::LoadSettingsFromConfig(const bool bLoadDefaults)
|
||||
{
|
||||
// Load the configuration from the INI file
|
||||
FConfigFile ConfigFile;
|
||||
|
||||
const FString Filename = GetConfigDirectoryFile();
|
||||
const FString Filename = GetConfigDirectoryFile(bLoadDefaults);
|
||||
|
||||
if (!GConfig)
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to access GConfig!"))
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to access GConfig!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -77,6 +93,20 @@ bool UHarmonyLinkGraphics::LoadSettingsFromConfig()
|
|||
// Load each profile section
|
||||
bool bLoaded = true;
|
||||
|
||||
// Load the _bAutomaticSwitch variable
|
||||
const FString SectionName = TEXT("HarmonyLink");
|
||||
const FString KeyName = TEXT("AutomaticProfileSwitch");
|
||||
|
||||
if (!GConfig->GetBool(*SectionName, *KeyName, _bAutomaticSwitch, Filename))
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to load bAutomaticSwitch from config"));
|
||||
bLoaded = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Log, TEXT("Loaded bAutomaticSwitch: %s"), _bAutomaticSwitch ? TEXT("true") : TEXT("false"));
|
||||
}
|
||||
|
||||
for (const TPair<EProfile, FName>& Profile : _ProfileNames)
|
||||
{
|
||||
if (!LoadSection(ConfigFile, Profile))
|
||||
|
@ -86,7 +116,7 @@ bool UHarmonyLinkGraphics::LoadSettingsFromConfig()
|
|||
}
|
||||
}
|
||||
|
||||
// Check if all profiles were loaded successfully
|
||||
// Check if all profiles and settings were loaded successfully
|
||||
if (bLoaded)
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Log, TEXT("Successfully loaded config file: %s"), *Filename);
|
||||
|
@ -95,7 +125,6 @@ bool UHarmonyLinkGraphics::LoadSettingsFromConfig()
|
|||
}
|
||||
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to load config file: %s"), *Filename);
|
||||
CreateDefaultConfigFile();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -151,20 +180,17 @@ bool UHarmonyLinkGraphics::LoadSection(const FConfigFile& ConfigFile, const TPai
|
|||
|
||||
void UHarmonyLinkGraphics::SaveConfig() const
|
||||
{
|
||||
QUICK_SCOPE_CYCLE_COUNTER(HarmonyLinkGraphics_SaveConfig);
|
||||
|
||||
for (TPair<EProfile, FSettingsProfile> Profile : _Profiles)
|
||||
{
|
||||
SaveSection(Profile.Value);
|
||||
}
|
||||
|
||||
const FString Filename = GetConfigDirectoryFile();
|
||||
UE_LOG(LogHarmonyLink, Log, TEXT("Flushing file: '%s'"), *Filename);
|
||||
GConfig->Flush(false, Filename);
|
||||
Intermal_SaveConfig(false);
|
||||
}
|
||||
|
||||
void UHarmonyLinkGraphics::SetSetting(const EProfile Profile, const FName Setting, const FHLConfigValue Value)
|
||||
{
|
||||
// Ignore if HarmonyLinkSettings is disabled
|
||||
if (Profile == EProfile::NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the profile name associated with the given EProfile
|
||||
const FName* ProfileName = _ProfileNames.Find(Profile);
|
||||
|
||||
|
@ -230,6 +256,12 @@ UHarmonyLinkGraphics* UHarmonyLinkGraphics::GetSettings()
|
|||
|
||||
FSettingsProfile UHarmonyLinkGraphics::GetSettingProfile(const EProfile Profile)
|
||||
{
|
||||
// Ignore if HarmonyLinkSettings is disabled
|
||||
if (Profile == EProfile::NONE)
|
||||
{
|
||||
return FSettingsProfile();
|
||||
}
|
||||
|
||||
// Find the profile name associated with the given EProfile
|
||||
const FName* ProfileName = _ProfileNames.Find(Profile);
|
||||
|
||||
|
@ -249,7 +281,6 @@ FSettingsProfile UHarmonyLinkGraphics::GetSettingProfile(const EProfile Profile)
|
|||
}
|
||||
|
||||
return *SettingsProfile;
|
||||
|
||||
}
|
||||
|
||||
EProfile UHarmonyLinkGraphics::GetActiveProfile() const
|
||||
|
@ -286,16 +317,35 @@ void UHarmonyLinkGraphics::Init()
|
|||
LoadConfig();
|
||||
|
||||
const FBattery BatteryStatus = UHarmonyLinkLibrary::GetBatteryStatus();
|
||||
|
||||
// Enabled for development testing
|
||||
// At some point I need to implement the ability to fake and emulate these settings to make it easier to test
|
||||
// BUG: Remove this before release!
|
||||
if (!BatteryStatus.HasBattery)
|
||||
|
||||
if (BatteryStatus.HasBattery)
|
||||
{
|
||||
ApplyProfileInternal(EProfile::BATTERY);
|
||||
}
|
||||
}
|
||||
|
||||
void UHarmonyLinkGraphics::Intermal_SaveConfig(const bool bDefaultConfig) const
|
||||
{
|
||||
QUICK_SCOPE_CYCLE_COUNTER(HarmonyLinkGraphics_SaveConfig);
|
||||
|
||||
const FString Filename = GetConfigDirectoryFile(bDefaultConfig);
|
||||
const FString SectionName = TEXT("HarmonyLink");
|
||||
const FString KeyName = TEXT("AutomaticProfileSwitch");
|
||||
|
||||
// Save the _bAutomaticSwitch variable
|
||||
GConfig->SetBool(*SectionName, *KeyName, _bAutomaticSwitch, Filename);
|
||||
|
||||
UE_LOG(LogHarmonyLink, Log, TEXT("Saving bAutomaticSwitch: %s"), _bAutomaticSwitch ? TEXT("true") : TEXT("false"));
|
||||
|
||||
for (const TPair<EProfile, FSettingsProfile>& Profile : _Profiles)
|
||||
{
|
||||
SaveSection(Profile.Value, bDefaultConfig);
|
||||
}
|
||||
|
||||
UE_LOG(LogHarmonyLink, Log, TEXT("Flushing file: '%s'"), *Filename);
|
||||
GConfig->Flush(true, Filename);
|
||||
}
|
||||
|
||||
void UHarmonyLinkGraphics::Tick()
|
||||
{
|
||||
Async(EAsyncExecution::Thread, [this]()
|
||||
|
@ -347,27 +397,23 @@ void UHarmonyLinkGraphics::CreateDefaultConfigFile()
|
|||
UE_LOG(LogHarmonyLink, Log, TEXT("Creating default config file."));
|
||||
|
||||
LoadDefaults();
|
||||
SaveConfig();
|
||||
Intermal_SaveConfig(true);
|
||||
|
||||
UE_LOG(LogHarmonyLink, Log, TEXT("Default config file created."));
|
||||
}
|
||||
|
||||
FString UHarmonyLinkGraphics::GetConfigDirectoryFile()
|
||||
FString UHarmonyLinkGraphics::GetConfigDirectoryFile(const bool bDefaultFolder)
|
||||
{
|
||||
FString ConfigFileName = "HarmonyLink.ini"; // Replace with your actual config file name
|
||||
FString ConfigFileName = bDefaultFolder? "DefaultHarmonyLink.ini" : "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
|
||||
return FPaths::Combine(bDefaultFolder ? FPaths::ProjectConfigDir() : FPaths::GeneratedConfigDir(), ConfigFileName);
|
||||
}
|
||||
|
||||
void UHarmonyLinkGraphics::SaveSection(FSettingsProfile& SettingsProfile, const bool bFlush)
|
||||
void UHarmonyLinkGraphics::SaveSection(const FSettingsProfile& SettingsProfile, const bool bDefaultConfig, const bool bFlush)
|
||||
{
|
||||
if (GConfig)
|
||||
{
|
||||
const FString Filename = GetConfigDirectoryFile();
|
||||
const FString Filename = GetConfigDirectoryFile(bDefaultConfig);
|
||||
for (const auto& Setting : SettingsProfile.Settings)
|
||||
{
|
||||
FString TypeString;
|
||||
|
@ -490,7 +536,7 @@ bool UHarmonyLinkGraphics::ApplyProfileInternal(const EProfile Profile)
|
|||
|
||||
void UHarmonyLinkGraphics::OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS)
|
||||
{
|
||||
if (!World)
|
||||
if (!World || !World->IsValidLowLevel())
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("Failed to Hook into World Initialisation!"))
|
||||
return;
|
||||
|
@ -498,18 +544,29 @@ void UHarmonyLinkGraphics::OnPostWorldInitialization(UWorld* World, UWorld::Init
|
|||
|
||||
if (World->IsGameWorld())
|
||||
{
|
||||
if (UHarmonyLinkGraphics* Settings = GetSettings())
|
||||
if (_INSTANCE)
|
||||
{
|
||||
if (World->IsPlayInEditor())
|
||||
FTimerManager* TimerManager = &World->GetTimerManager();
|
||||
if (!TimerManager)
|
||||
{
|
||||
Settings->LoadConfig(true);
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("Failed get TimerManager!"))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!World->GetTimerManager().TimerExists(Settings->_TickTimerHandle) || !World->GetTimerManager().IsTimerActive(Settings->_TickTimerHandle))
|
||||
|
||||
if (!TimerManager->TimerExists(_INSTANCE->_TickTimerHandle) || !TimerManager->IsTimerActive(_INSTANCE->_TickTimerHandle))
|
||||
{
|
||||
World->GetTimerManager().SetTimer(Settings->_TickTimerHandle, [Settings]
|
||||
World->GetTimerManager().SetTimer(_INSTANCE->_TickTimerHandle, [&, TimerManager]
|
||||
{
|
||||
Settings->Tick();
|
||||
if (!this)
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("'This' is destroyed, Clearing timer."))
|
||||
if (TimerManager)
|
||||
{
|
||||
TimerManager->ClearTimer(_TickTimerHandle);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Tick();
|
||||
}, _TickRate, true);
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +575,7 @@ void UHarmonyLinkGraphics::OnPostWorldInitialization(UWorld* World, UWorld::Init
|
|||
|
||||
void UHarmonyLinkGraphics::OnWorldEnd(UWorld* World)
|
||||
{
|
||||
if (!World)
|
||||
if (!World || !World->IsValidLowLevel())
|
||||
{
|
||||
UE_LOG(LogHarmonyLink, Error, TEXT("World Already destroyed"))
|
||||
return;
|
||||
|
@ -533,10 +590,10 @@ void UHarmonyLinkGraphics::OnWorldEnd(UWorld* World)
|
|||
DestroySettings();
|
||||
}
|
||||
|
||||
bool UHarmonyLinkGraphics::ApplyProfile(const EProfile Profile, const bool bDisableAuto)
|
||||
bool UHarmonyLinkGraphics::ApplyProfile(const EProfile Profile, const bool bDisableAutomaticSwitch)
|
||||
{
|
||||
// Manual profile change, turn off automatic switching
|
||||
if (bDisableAuto)
|
||||
if (bDisableAutomaticSwitch)
|
||||
{
|
||||
_bAutomaticSwitch = false;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "CoreMinimal.h"
|
||||
#include "Platform.generated.h"
|
||||
|
||||
// Undefine the LINUX macro to avoid conflicts with the enum definition.
|
||||
#undef LINUX
|
||||
|
||||
/*
|
||||
* Enum representing different operating system platforms.
|
||||
*/
|
||||
|
|
|
@ -33,81 +33,468 @@ public:
|
|||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnBatteryLevelChanged OnBatteryLevelChanged;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Loads the graphics configuration settings.
|
||||
*
|
||||
* This function loads the graphics settings into the appropriate map. If the initial loading attempt fails,
|
||||
* it retries a second time. The settings are loaded using the `LoadSettingsFromConfig` method.
|
||||
* After loading the settings, the function prints debug information about the profiles.
|
||||
*
|
||||
* @param bForceReload Indicates whether to force reload the settings. Defaults to false.
|
||||
*
|
||||
* @note This function uses the QUICK_SCOPE_CYCLE_COUNTER macro for performance profiling.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||
void LoadConfig(const bool bForceReload = false);
|
||||
|
||||
/**
|
||||
* @brief Saves the current graphics configuration settings to the configuration file.
|
||||
*
|
||||
* This function iterates through all profiles and saves their settings to the configuration file.
|
||||
* Additionally, it saves the `_bAutomaticSwitch` variable to the configuration file and flushes the changes.
|
||||
*
|
||||
* @details
|
||||
* - Uses the QUICK_SCOPE_CYCLE_COUNTER macro for performance profiling.
|
||||
* - Iterates through the `_Profiles` map and calls `SaveSection` for each profile to save its settings.
|
||||
* - Saves the `_bAutomaticSwitch` variable under the "HarmonyLink" section with the key "AutomaticProfileSwitch".
|
||||
* - Logs the status of `_bAutomaticSwitch` and flushes the configuration file to ensure all changes are written.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the save process and status messages.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||
void SaveConfig() const;
|
||||
|
||||
/**
|
||||
* @brief Sets a specific configuration value for a given profile.
|
||||
*
|
||||
* This function updates a setting for a specified profile with a new value. It handles various data types (int, float, bool, string)
|
||||
* and logs the process. If the profile or settings cannot be found, it logs an error message.
|
||||
*
|
||||
* @param Profile The profile identifier for which the setting is to be updated.
|
||||
* @param Setting The name of the setting to update.
|
||||
* @param Value The new value to set for the specified setting.
|
||||
*
|
||||
* @details
|
||||
* - Finds the profile name associated with the given `EProfile`.
|
||||
* - Determines the type of the value and converts it to a string.
|
||||
* - Logs the application of the setting with its value and type.
|
||||
* - Finds the settings profile associated with the given profile.
|
||||
* - Updates the setting with the new value or adds it if it does not exist.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the update process and any errors.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||
void SetSetting(EProfile Profile, FName Setting, FHLConfigValue Value);
|
||||
|
||||
/**
|
||||
* @brief Applies the specified graphics profile.
|
||||
*
|
||||
* This function applies the given graphics profile. If automatic profile switching is enabled, it can be disabled by setting the `bDisableAutomaticSwitch` parameter to true.
|
||||
*
|
||||
* @param Profile The profile to apply.
|
||||
* @param bDisableAutomaticSwitch Indicates whether to disable automatic profile switching. Defaults to true.
|
||||
* @return bool Returns true if the profile was successfully applied; false otherwise.
|
||||
*
|
||||
* @details
|
||||
* - If `bDisableAutomaticSwitch` is true, sets `_bAutomaticSwitch` to false to disable automatic profile switching.
|
||||
* - Calls `ApplyProfileInternal` to apply the specified profile.
|
||||
* - Returns the result of `ApplyProfileInternal`.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||
bool ApplyProfile(EProfile Profile, const bool bDisableAuto = true);
|
||||
bool ApplyProfile(EProfile Profile, const bool bDisableAutomaticSwitch = true);
|
||||
|
||||
/** Returns the game local machine settings (resolution, windowing mode, scalability settings, etc...) */
|
||||
/**
|
||||
* @brief Retrieves the singleton instance of the UHarmonyLinkGraphics settings.
|
||||
*
|
||||
* This function returns the singleton instance of the `UHarmonyLinkGraphics` class. If the instance has not been
|
||||
* initialized, it creates a new instance, adds it to the root to prevent garbage collection, initializes it, and
|
||||
* then returns the instance.
|
||||
*
|
||||
* @return UHarmonyLinkGraphics* The singleton instance of the `UHarmonyLinkGraphics` class.
|
||||
*
|
||||
* @details
|
||||
* - Checks if the singleton instance (`_INSTANCE`) is already initialized.
|
||||
* - If not, creates a new instance using `NewObject<UHarmonyLinkGraphics>`.
|
||||
* - Adds the new instance to the root to prevent it from being garbage collected.
|
||||
* - Calls the `Init` function on the new instance to perform any necessary initialization.
|
||||
* - Returns the singleton instance.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||
static UHarmonyLinkGraphics* GetSettings();
|
||||
|
||||
/**
|
||||
* @brief Retrieves the settings profile for a specified profile.
|
||||
*
|
||||
* This function returns the settings profile associated with the given `EProfile`. If the profile name or the settings
|
||||
* cannot be found, it logs an error message and returns an empty `FSettingsProfile`.
|
||||
*
|
||||
* @param Profile The profile identifier for which the settings profile is to be retrieved.
|
||||
* @return FSettingsProfile The settings profile associated with the specified profile. If the profile is not found, returns an empty `FSettingsProfile`.
|
||||
*
|
||||
* @details
|
||||
* - Finds the profile name associated with the given `EProfile`.
|
||||
* - Logs an error and returns an empty `FSettingsProfile` if the profile name is not found.
|
||||
* - Finds the settings profile associated with the profile.
|
||||
* - Logs an error and returns an empty `FSettingsProfile` if the settings profile is not found.
|
||||
* - Returns the settings profile if found.
|
||||
*
|
||||
* @note Uses UE_LOG for logging errors.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="HarmonyLink Settings")
|
||||
FSettingsProfile GetSettingProfile(const EProfile Profile);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the currently active profile.
|
||||
*
|
||||
* This function returns the currently active profile of the `UHarmonyLinkGraphics` settings.
|
||||
*
|
||||
* @return EProfile The currently active profile.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="HarmonyLink Settings")
|
||||
EProfile GetActiveProfile() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the automatic profile switching state.
|
||||
*
|
||||
* This function updates the automatic profile switching setting and broadcasts the change.
|
||||
*
|
||||
* @param bAutomaticSwitch Indicates whether automatic profile switching should be enabled (true) or disabled (false).
|
||||
*
|
||||
* @details
|
||||
* - Updates the `_bAutomaticSwitch` member variable with the new value.
|
||||
* - Broadcasts the change to any listeners using the `OnAutomaticSwitchChanged` delegate.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="HarmonyLink Settings")
|
||||
void SetAutomaticSwitching(const bool bAutomaticSwitch);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current state of automatic profile switching.
|
||||
*
|
||||
* This function returns the state of the automatic profile switching setting.
|
||||
*
|
||||
* @return bool True if automatic profile switching is enabled; false otherwise.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="HarmonyLink Settings")
|
||||
bool GetAutomaticSwitching() const;
|
||||
|
||||
/**
|
||||
* @brief Destroys the singleton instance of the UHarmonyLinkGraphics settings.
|
||||
*
|
||||
* This function safely destroys the singleton instance of the `UHarmonyLinkGraphics` class by removing it from root,
|
||||
* marking it as garbage for cleanup, and setting the instance pointer to null.
|
||||
*
|
||||
* @details
|
||||
* - Checks if the singleton instance (`_INSTANCE`) exists.
|
||||
* - Logs the destruction of the `UHarmonyLinkGraphics` instance.
|
||||
* - Removes all delegate bindings from `_INSTANCE`.
|
||||
* - Removes `_INSTANCE` from the root to allow garbage collection.
|
||||
* - Marks `_INSTANCE` as garbage to enable cleanup.
|
||||
* - Sets `_INSTANCE` to null.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the destruction process.
|
||||
*/
|
||||
static void DestroySettings();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Initializes the UHarmonyLinkGraphics settings.
|
||||
*
|
||||
* This function initializes the `UHarmonyLinkGraphics` settings by loading the configuration and applying the
|
||||
* appropriate profile based on the battery status.
|
||||
*
|
||||
* @details
|
||||
* - Calls `LoadConfig` to load the configuration settings.
|
||||
* - Retrieves the current battery status using `UHarmonyLinkLibrary::GetBatteryStatus`.
|
||||
* - If the device has a battery, applies the `BATTERY` profile by calling `ApplyProfileInternal`.
|
||||
*/
|
||||
void Init();
|
||||
|
||||
void Intermal_SaveConfig(const bool bDefaultConfig) const;
|
||||
|
||||
/**
|
||||
* @brief Periodically checks and updates the battery status and profile settings.
|
||||
*
|
||||
* This function is executed based on a timer determined by `_TickRate`. It asynchronously checks the current battery status
|
||||
* and updates the battery percentage and profile settings as needed. If the battery percentage has changed, it broadcasts
|
||||
* this change. If automatic profile switching is enabled, it applies the appropriate profile based on the AC connection status.
|
||||
*
|
||||
* @details
|
||||
* - Runs asynchronously on a separate thread to fetch the current battery status using `UHarmonyLinkLibrary::GetBatteryStatus`.
|
||||
* - If the battery percentage has changed, broadcasts the new battery percentage in a thread-safe manner.
|
||||
* - If automatic profile switching (`_bAutomaticSwitch`) is disabled, exits the function.
|
||||
* - If the device has a battery:
|
||||
* - Checks the AC connection status and applies the `CHARGING` profile if connected to AC.
|
||||
* - Applies the `BATTERY` profile if not connected to AC.
|
||||
* - Ensures all profile applications and broadcasts are executed on the main thread for thread safety.
|
||||
*
|
||||
* @note Uses UE_LOG for logging and `Async` for asynchronous execution.
|
||||
*/
|
||||
void Tick();
|
||||
|
||||
/**
|
||||
* @brief Creates a default configuration file.
|
||||
*
|
||||
* This function creates a default configuration file by loading the default settings and then saving them to the config file.
|
||||
*
|
||||
* @details
|
||||
* - Logs the start of the default configuration file creation process.
|
||||
* - Calls `LoadDefaults` to load the default settings into the configuration.
|
||||
* - Calls `SaveConfig` to save the default settings to the configuration file.
|
||||
* - Logs the completion of the default configuration file creation process.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the creation process.
|
||||
*/
|
||||
void CreateDefaultConfigFile();
|
||||
static FString GetConfigDirectoryFile();
|
||||
bool LoadSettingsFromConfig();
|
||||
|
||||
/**
|
||||
* @brief Retrieves the path to the configuration file.
|
||||
*
|
||||
* This function constructs and returns the full path to the configuration file used by the `UHarmonyLinkGraphics` settings.
|
||||
*
|
||||
* @return FString The full path to the configuration file.
|
||||
*
|
||||
* @details
|
||||
* - Defines the configuration file name as "HarmonyLink.ini".
|
||||
* - Combines the generated config directory path with the configuration file name to form the full path.
|
||||
* - Returns the full path to the configuration file.
|
||||
*/
|
||||
static FString GetConfigDirectoryFile(const bool bDefaultFolder);
|
||||
|
||||
/**
|
||||
* @brief Loads the settings from the configuration file.
|
||||
*
|
||||
* This function loads the graphics settings from an INI configuration file into the appropriate structures.
|
||||
* It attempts to load each profile section and the automatic switch setting. If any section fails to load,
|
||||
* it logs an error message and indicates failure. If loading is successful, it logs a success message.
|
||||
*
|
||||
* @return true if the settings were successfully loaded; false otherwise.
|
||||
*
|
||||
* @details
|
||||
* - Loads the configuration file specified by `GetConfigDirectoryFile`.
|
||||
* - Iterates over the `_ProfileNames` to load each profile section.
|
||||
* - Loads the `_bAutomaticSwitch` variable from the config.
|
||||
* - If loading fails, it attempts to create a default configuration file.
|
||||
*
|
||||
* @note Uses UE_LOG for logging errors and success messages.
|
||||
*/
|
||||
bool LoadSettingsFromConfig(const bool bLoadDefaults);
|
||||
|
||||
/**
|
||||
* @brief Loads a specific section from the configuration file into a settings profile.
|
||||
*
|
||||
* This function extracts settings from a specified section of the configuration file and stores them in the corresponding profile.
|
||||
* It handles different data types (int, float, bool, string) and parses them accordingly. If the section is found and loaded successfully,
|
||||
* the settings are added to the profile's settings map.
|
||||
*
|
||||
* @param ConfigFile The configuration file from which to load the section.
|
||||
* @param Profile The profile key-value pair containing the profile enum and the section name.
|
||||
* @return true if the section was found and loaded successfully; false otherwise.
|
||||
*
|
||||
* @details
|
||||
* - Finds the section in the configuration file using the section name from the profile.
|
||||
* - Clears any previous settings in the profile.
|
||||
* - Iterates through the settings in the section, parsing the value and type, and adds them to the profile's settings map.
|
||||
*
|
||||
* @note The function handles settings of types int, float, bool, and string.
|
||||
*/
|
||||
bool LoadSection(const FConfigFile& ConfigFile, const TPair<EProfile, FName> Profile);
|
||||
static void SaveSection(FSettingsProfile& SettingsProfile, const bool bFlush = false);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Saves the settings of a given profile section to the configuration file.
|
||||
*
|
||||
* This function saves the settings of a specified profile section to the configuration file. It handles various data types
|
||||
* (int, float, bool, string) and formats them accordingly before saving. If the `bFlush` parameter is true, the configuration
|
||||
* file is flushed to ensure all changes are written to disk.
|
||||
*
|
||||
* @param SettingsProfile The settings profile to be saved.
|
||||
* @param bFlush Indicates whether to flush the configuration file after saving. Defaults to false.
|
||||
*
|
||||
* @details
|
||||
* - Checks if the global configuration object (`GConfig`) is available.
|
||||
* - Constructs the full path to the configuration file using `GetConfigDirectoryFile`.
|
||||
* - Iterates through the settings in the provided `SettingsProfile`.
|
||||
* - Determines the type and value of each setting and formats them as strings.
|
||||
* - Sets the formatted string in the configuration file for each setting.
|
||||
* - Logs the save operation.
|
||||
* - If `bFlush` is true, flushes the configuration file to ensure all changes are written.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the save and flush operations.
|
||||
*/
|
||||
static void SaveSection(const FSettingsProfile& SettingsProfile, const bool bDefaultConfig, const bool bFlush = false);
|
||||
|
||||
/**
|
||||
* @brief Loads the default settings into the profiles.
|
||||
*
|
||||
* This function resets the current profiles and loads the default settings into the profiles. It iterates over the profile names
|
||||
* and assigns the default settings to each profile.
|
||||
*
|
||||
* @details
|
||||
* - Logs the start of the `LoadDefaults` process.
|
||||
* - Resets the `_Profiles` map to clear any existing settings.
|
||||
* - Iterates over `_ProfileNames` to create default settings for each profile.
|
||||
* - For each profile, initializes a `FSettingsProfile` with the section name.
|
||||
* - If default settings are found for the profile in `_DefaultSettings`, assigns these settings to the profile.
|
||||
* - Adds the newly created profile settings to `_Profiles`.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the start of the default settings loading process.
|
||||
*/
|
||||
void LoadDefaults();
|
||||
|
||||
/**
|
||||
* @brief Applies the specified graphics profile internally.
|
||||
*
|
||||
* This function applies the given graphics profile by either reverting to the original user game settings or
|
||||
* applying the settings associated with the specified profile.
|
||||
*
|
||||
* @param Profile The profile to apply. If the profile is `EProfile::NONE`, the function reverts to the original user game settings.
|
||||
* @return bool Returns true if the profile was successfully applied; false otherwise.
|
||||
*
|
||||
* @details
|
||||
* - If the `Profile` is `EProfile::NONE`:
|
||||
* - Logs a message indicating reversion to original user game settings.
|
||||
* - Retrieves the user game settings and applies them.
|
||||
* - Sets `_ActiveProfile` to `EProfile::NONE` and broadcasts the profile change.
|
||||
* - Returns true if successful, false otherwise.
|
||||
* - Finds the profile name associated with the given `EProfile`.
|
||||
* - Logs an error and returns false if the profile name is not found.
|
||||
* - Logs a message indicating the profile being applied.
|
||||
* - Finds the settings associated with the profile.
|
||||
* - Logs a warning and returns false if the settings profile is not found.
|
||||
* - Creates a render state context for applying settings.
|
||||
* - Iterates through each setting in the profile and applies it using `ApplySetting`.
|
||||
* - Sets `_ActiveProfile` to the specified profile and broadcasts the profile change.
|
||||
* - Returns true indicating the profile was successfully applied.
|
||||
*
|
||||
* @note Uses UE_LOG for logging messages, warnings, and errors. Uses `OnProfileChanged` to broadcast profile changes.
|
||||
*/
|
||||
bool ApplyProfileInternal(EProfile Profile);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handles actions to be performed after the world initialization.
|
||||
*
|
||||
* This function hooks into the world initialization process to set up the `UHarmonyLinkGraphics` settings.
|
||||
* It checks if the world is valid and is a game world, then initializes or reloads the settings as necessary and sets up a timer for periodic updates.
|
||||
*
|
||||
* @param World The world that has just been initialized.
|
||||
* @param IVS Initialization values for the world.
|
||||
*
|
||||
* @details
|
||||
* - Checks if the `World` pointer is valid. Logs an error and returns if the world is invalid.
|
||||
* - If the world is a game world:
|
||||
* - Retrieves the singleton settings instance using `GetSettings`.
|
||||
* - If the world is a play-in-editor world, reloads the settings configuration by calling `LoadConfig` with `bForceReload` set to true.
|
||||
* - Checks if the tick timer is already set or active. If not, sets a timer to call the `Tick` function at intervals specified by `_TickRate`.
|
||||
*
|
||||
* @note Uses UE_LOG for logging errors and informational messages.
|
||||
*/
|
||||
void OnPostWorldInitialization(UWorld* World, UWorld::InitializationValues IVS);
|
||||
|
||||
/**
|
||||
* @brief Handles actions to be performed when the world ends.
|
||||
*
|
||||
* This function is called when the world is about to be destroyed. It clears the tick timer and safely destroys the singleton instance of the `UHarmonyLinkGraphics` settings.
|
||||
*
|
||||
* @param World The world that is ending.
|
||||
*
|
||||
* @details
|
||||
* - Checks if the `World` pointer is valid. Logs an error and returns if the world is already destroyed.
|
||||
* - If the tick timer exists, clears the timer using the world's timer manager.
|
||||
* - Calls `DestroySettings` to safely destroy the singleton instance of `UHarmonyLinkGraphics`.
|
||||
*
|
||||
* @note Uses UE_LOG for logging errors and informational messages.
|
||||
*/
|
||||
void OnWorldEnd(UWorld* World);
|
||||
|
||||
/**
|
||||
* @brief Resets the singleton instance of the UHarmonyLinkGraphics settings.
|
||||
*
|
||||
* This function resets the singleton instance by destroying the current instance and creating a new one.
|
||||
*
|
||||
* @details
|
||||
* - Calls `DestroySettings` on the current instance to safely destroy it.
|
||||
* - Calls `GetSettings` to create and initialize a new singleton instance.
|
||||
*/
|
||||
static void ResetInstance();
|
||||
|
||||
// Note: Turning off HarmonyLink Settings requires game restart
|
||||
/**
|
||||
* @brief Applies a specific configuration setting to the console variable.
|
||||
*
|
||||
* This function applies the given configuration setting to the corresponding console variable (CVar) based on its key. It supports different data types such as bool, float, and int.
|
||||
*
|
||||
* @param Setting The key-value pair representing the setting to apply. The key is the name of the console variable, and the value is the configuration value.
|
||||
*
|
||||
* @details
|
||||
* - Uses the console manager to find the console variable associated with the given setting key.
|
||||
* - Depending on the type of the configuration value, sets the console variable to the corresponding value.
|
||||
* - If the console variable is not found, logs a warning message.
|
||||
* - If the value type is unsupported, logs a warning message.
|
||||
*
|
||||
* @note Uses UE_LOG for logging warnings about unsupported value types or missing console variables.
|
||||
*/
|
||||
static void ApplySetting(const TPair<FName, FHLConfigValue>& Setting);
|
||||
|
||||
// Debugging
|
||||
/**
|
||||
* @brief Prints debug information for all profiles.
|
||||
*
|
||||
* This function logs the debug information for all profiles stored in `_Profiles`. It iterates through each profile and calls `PrintDebugSection` to print the details.
|
||||
*
|
||||
* @details
|
||||
* - Logs the start of the `DebugPrintProfiles` process.
|
||||
* - Iterates over each profile in the `_Profiles` map.
|
||||
* - Calls `PrintDebugSection` for each profile to print its details.
|
||||
* - Logs the completion of the `DebugPrintProfiles` process.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the start and completion of the debug print process.
|
||||
*/
|
||||
void DebugPrintProfiles() const;
|
||||
|
||||
/**
|
||||
* @brief Prints debug information for a specific settings profile.
|
||||
*
|
||||
* This function logs the debug information for a given settings profile, including the section name and each setting's key, value, and type.
|
||||
*
|
||||
* @param SettingsProfile The settings profile to print debug information for.
|
||||
*
|
||||
* @details
|
||||
* - Logs the section name of the `SettingsProfile`.
|
||||
* - Iterates through each setting in the `SettingsProfile`.
|
||||
* - Depending on the type of each setting, converts the value to a string and logs the key, value, and type.
|
||||
*
|
||||
* @note Uses UE_LOG for logging the section name and settings details.
|
||||
*/
|
||||
static void PrintDebugSection(FSettingsProfile& SettingsProfile);
|
||||
|
||||
uint8 _bAutomaticSwitch :1;
|
||||
// Indicates whether automatic profile switching is enabled.
|
||||
bool _bAutomaticSwitch = false;
|
||||
|
||||
// Stores the last recorded battery percentage.
|
||||
int32 _LastBatteryPercentage = 0;
|
||||
|
||||
// How many times to query HarmonyLinkLib for hardware info
|
||||
// The rate at which to query HarmonyLinkLib for hardware info.
|
||||
static int32 _TickRate;
|
||||
|
||||
FTimerHandle _TickTimerHandle;
|
||||
// Timer handle for managing the periodic tick function.
|
||||
static FTimerHandle _TickTimerHandle;
|
||||
|
||||
// The currently active profile.
|
||||
EProfile _ActiveProfile = EProfile::NONE;
|
||||
|
||||
// Maps profile enums to their corresponding names.
|
||||
TMap<EProfile, FName> _ProfileNames = {
|
||||
{EProfile::BATTERY, "Battery"},
|
||||
{EProfile::CHARGING, "Charging"},
|
||||
{EProfile::DOCKED, "Docked"},
|
||||
};
|
||||
|
||||
// Stores the settings profiles.
|
||||
TMap<EProfile, FSettingsProfile> _Profiles;
|
||||
|
||||
// The default settings for profiles.
|
||||
static TMap<FName, TMap<FName, FHLConfigValue>> _DefaultSettings;
|
||||
|
||||
// Singleton instance of UHarmonyLinkGraphics.
|
||||
static UHarmonyLinkGraphics* _INSTANCE;
|
||||
};
|
||||
|
|
BIN
Source/ThirdParty/HarmonyLinkLib/bin/Linux/libHarmonyLinkLib.so
(Stored with Git LFS)
vendored
BIN
Source/ThirdParty/HarmonyLinkLib/bin/Linux/libHarmonyLinkLib.so
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Source/ThirdParty/HarmonyLinkLib/bin/Win64/HarmonyLinkLib.dll
(Stored with Git LFS)
vendored
BIN
Source/ThirdParty/HarmonyLinkLib/bin/Win64/HarmonyLinkLib.dll
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Source/ThirdParty/HarmonyLinkLib/bin/Win64/HarmonyLinkLib.lib
(Stored with Git LFS)
vendored
BIN
Source/ThirdParty/HarmonyLinkLib/bin/Win64/HarmonyLinkLib.lib
(Stored with Git LFS)
vendored
Binary file not shown.
10
Source/ThirdParty/HarmonyLinkLib/include/Core.h
vendored
10
Source/ThirdParty/HarmonyLinkLib/include/Core.h
vendored
|
@ -16,10 +16,14 @@
|
|||
|
||||
// Use a preprocessor definition to switch between export and import declarations
|
||||
#ifdef _WIN32
|
||||
#ifdef HARMONYLINKLIB_EXPORTS
|
||||
#define HARMONYLINKLIB_API __declspec(dllexport)
|
||||
#ifdef HARMONYLINKLIB_STATIC
|
||||
#define HARMONYLINKLIB_API
|
||||
#else
|
||||
#define HARMONYLINKLIB_API __declspec(dllimport)
|
||||
#ifdef HARMONYLINKLIB_SHARED
|
||||
#define HARMONYLINKLIB_API __declspec(dllexport)
|
||||
#else
|
||||
#define HARMONYLINKLIB_API __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define HARMONYLINKLIB_API
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Undefine the LINUX macro to avoid conflicts with the enum definition.
|
||||
#undef LINUX
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Enum class for representing different types of devices
|
||||
|
|
BIN
Source/ThirdParty/HarmonyLinkLib/lib/Linux/libHarmonyLinkLibStatic.a
(Stored with Git LFS)
vendored
Normal file
BIN
Source/ThirdParty/HarmonyLinkLib/lib/Linux/libHarmonyLinkLibStatic.a
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
BIN
Source/ThirdParty/HarmonyLinkLib/lib/Win64/HarmonyLinkLibStatic.lib
(Stored with Git LFS)
vendored
Normal file
BIN
Source/ThirdParty/HarmonyLinkLib/lib/Win64/HarmonyLinkLibStatic.lib
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue