Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade v4 #18

Merged
merged 36 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8506bdb
updated includes to v4
pasotee Apr 23, 2024
c0642b6
updating logger
pasotee Apr 23, 2024
4fdfc90
fixed network adapter errors
pasotee Apr 23, 2024
e5a7a0e
Updated hooks API
pasotee Apr 24, 2024
b7225c5
force fix all compilation errors
pasotee Apr 24, 2024
f50f6aa
Enable exception to build for target platforms properly
pasotee Apr 26, 2024
db8e2c3
update includes from cpp-sdk after PR approval
pasotee Apr 26, 2024
21a8dcb
starting to re-work wrappers
pasotee Apr 29, 2024
0e2c4fc
wrapper refactor to UObjects
pasotee Apr 30, 2024
1ba6aa6
improved wrappers structure
pasotee Apr 30, 2024
3a24e3e
added workflow dispatch to manually trigger runs
pasotee May 4, 2024
cd99a56
Fixed crash when no user is provided
pasotee May 4, 2024
4fcb82b
Merge branch 'upgrade-v4' of https://github.com/configcat/unreal-engi…
pasotee May 5, 2024
a90cedc
temp refactor
pasotee May 12, 2024
a390945
wrappers new classes
pasotee May 12, 2024
75872a3
Finished settings wrapper
pasotee May 12, 2024
f2133cf
Finished one more wrapper
pasotee May 12, 2024
c4a1422
started implementation for the last 2 wrappers
pasotee May 12, 2024
ceceffa
Percentageoption done
pasotee May 12, 2024
71eaf9a
fixed includes for PR CI
pasotee May 13, 2024
3db8965
missing include for CI
pasotee May 13, 2024
5f10108
WIP targeting rules wrapper
pasotee May 14, 2024
085f36a
wrappers for targeting rules
pasotee May 15, 2024
f9ca35d
separate module for wrappers
pasotee May 15, 2024
437ba49
moved wrapper classes to separate module
pasotee May 15, 2024
6ed37c9
fixed nullptr crashes
pasotee May 15, 2024
de0fced
enable wrapper classes to show up in blueprints
pasotee May 15, 2024
a54bd75
fixed macos compiler error
pasotee May 15, 2024
96f0e0b
Merge branch 'upgrade-v4' of https://github.com/configcat/unreal-engi…
pasotee May 15, 2024
f1bb1d2
fixed CI - wrapper exceptions + missing shared_ptr include
pasotee May 15, 2024
278e206
Apply suggestions from code review
pasotee May 22, 2024
45a1e9e
fixed wrong copyright notice
pasotee May 22, 2024
1256470
one more missing copyright
pasotee May 22, 2024
7129e83
Ensure Wrapper
pasotee May 22, 2024
4522590
implemented missing methods
pasotee May 22, 2024
473727e
versioning for VCPKG library
pasotee May 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/plugin-cd.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Plugin CD

on:
workflow_dispatch:
push:
tags:
- 'v*'
Expand Down
6 changes: 6 additions & 0 deletions ConfigCat.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"LoadingPhase": "PreDefault",
"PlatformAllowList": [ "Win64", "Mac", "Linux", "Android", "iOS" ]
},
{
"Name": "ConfigCatWrappers",
"Type": "Runtime",
"LoadingPhase": "PreDefault",
"PlatformAllowList": [ "Win64", "Mac", "Linux", "Android", "iOS" ]
},
{
"Name": "ConfigCatEditor",
"Type": "Editor",
Expand Down
3 changes: 3 additions & 0 deletions Source/ConfigCat/ConfigCat.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public ConfigCat(ReadOnlyTargetRules Target) : base(Target)

PrivateDependencyModuleNames.AddRange(new[]
{
"ConfigCatWrappers",
"ConfigCatCppSdk"
});

Expand All @@ -31,5 +32,7 @@ public ConfigCat(ReadOnlyTargetRules Target) : base(Target)

PrivateDefinitions.Add("CONFIGCAT_HTTPTHREAD_WORKAROUND");
}

bEnableExceptions = true;
}
}
8 changes: 7 additions & 1 deletion Source/ConfigCat/Private/ConfigCatLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ FConfigCatLogger::FConfigCatLogger() : ILogger(LOG_LEVEL_DEBUG)
{
}

void FConfigCatLogger::log(configcat::LogLevel level, const std::string& message)
void FConfigCatLogger::log(configcat::LogLevel level, const std::string& message, const std::exception_ptr& exception)
{
const FString& LogMessage = UTF8_TO_TCHAR(message.c_str());

Expand All @@ -32,4 +32,10 @@ void FConfigCatLogger::log(configcat::LogLevel level, const std::string& message
UE_LOG(LogConfigCat, Log, TEXT("[CPP-SDK] %s"), *LogMessage);
break;
}

if(exception)
pasotee marked this conversation as resolved.
Show resolved Hide resolved
{
const FString ExceptionMessage = UTF8_TO_TCHAR(unwrap_exception_message(exception).c_str());
UE_LOG(LogConfigCat, Error, TEXT("[CPP-SDK] Exception: %s"), *ExceptionMessage);
}
}
2 changes: 1 addition & 1 deletion Source/ConfigCat/Private/ConfigCatNetworkAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Response ConfigCatNetworkAdapter::get(
if (!GetResponse)
{
Response.error = "Unreal Engine Network Adapter failed to launch request. Check logs";
Response.operationTimedOut = GetRequest->GetElapsedTime() > Timeout;
Response.errorCode = ResponseErrorCode::InternalError;
return Response;
}

Expand Down
108 changes: 49 additions & 59 deletions Source/ConfigCat/Private/ConfigCatSubsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,41 @@
#include "ConfigCatLogger.h"
#include "ConfigCatNetworkAdapter.h"
#include "ConfigCatSettings.h"
#include "Wrapper/ConfigCatEvaluationDetails.h"
#include "Wrapper/ConfigCatUser.h"
#include "Wrapper/ConfigCatValue.h"
#include "ConfigCatSettingsWrapper.h"
#include "ConfigCatEvaluationWrapper.h"
#include "ConfigCatUserWrapper.h"
#include "ConfigCatValueWrapper.h"

using namespace configcat;

namespace
{
template <typename T>
T GetValue(ConfigCatClient* Client, FString Key, T DefaultValue, const FConfigCatUser& User)
T GetValue(const std::shared_ptr<ConfigCatClient>& Client, FString Key, T DefaultValue, const UConfigCatUserWrapper* User)
{
if (!ensure(Client))
{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
return DefaultValue;
}

const ConfigCatUser* TargetUser = User.User.get();
const std::string& FlagKey = TCHAR_TO_UTF8(*Key);

return Client->getValue(FlagKey, DefaultValue, TargetUser);
return Client->getValue(FlagKey, DefaultValue, User ? User->User : nullptr);
}

template <typename T>
EvaluationDetails GetEvaluationDetails(ConfigCatClient* Client, FString Key, T DefaultValue, const FConfigCatUser& User)
UConfigCatEvaluationWrapper* GetEvaluationDetails(const std::shared_ptr<ConfigCatClient>& Client, FString Key, T DefaultValue, const UConfigCatUserWrapper* User)
{
if (!ensure(Client))
{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
return {};
}

const ConfigCatUser* TargetUser = User.User.get();
const std::string& FlagKey = TCHAR_TO_UTF8(*Key);

return Client->getValueDetails(FlagKey, DefaultValue, TargetUser);
return UConfigCatEvaluationWrapper::CreateEvaluation(Client->getValueDetails(FlagKey, DefaultValue, User ? User->User : nullptr));
}
} // namespace

Expand All @@ -64,60 +63,59 @@ UConfigCatSubsystem* UConfigCatSubsystem::Get(const UObject* WorldContext)
return GameInstance->GetSubsystem<UConfigCatSubsystem>();
}

bool UConfigCatSubsystem::GetBoolValue(const FString& Key, bool bDefaultValue, const FConfigCatUser& User) const
bool UConfigCatSubsystem::GetBoolValue(const FString& Key, bool bDefaultValue, const UConfigCatUserWrapper* User) const
{
return GetValue(ConfigCatClient, Key, bDefaultValue, User);
}

int32 UConfigCatSubsystem::GetIntValue(const FString& Key, int32 DefaultValue, const FConfigCatUser& User) const
int32 UConfigCatSubsystem::GetIntValue(const FString& Key, int32 DefaultValue, const UConfigCatUserWrapper* User) const
{
return GetValue(ConfigCatClient, Key, DefaultValue, User);
}

double UConfigCatSubsystem::GetDoubleValue(const FString& Key, double DefaultValue, const FConfigCatUser& User) const
double UConfigCatSubsystem::GetDoubleValue(const FString& Key, double DefaultValue, const UConfigCatUserWrapper* User) const
{
return GetValue(ConfigCatClient, Key, DefaultValue, User);
}

FString UConfigCatSubsystem::GetStringValue(const FString& Key, const FString& DefaultValue, const FConfigCatUser& User) const
FString UConfigCatSubsystem::GetStringValue(const FString& Key, const FString& DefaultValue, const UConfigCatUserWrapper* User) const
{
UE_LOG(LogConfigCat, Display, TEXT("Request %s feature flag from configcat cpp-sdk"), *Key);
const std::string& StringDefaultValue = TCHAR_TO_UTF8(*DefaultValue);
const std::string& StringResult = GetValue(ConfigCatClient, Key, StringDefaultValue, User);
return UTF8_TO_TCHAR(StringResult.c_str());
}

FConfigCatValue UConfigCatSubsystem::GetConfigValue(const FString& Key, const FConfigCatUser& User) const
UConfigCatValueWrapper* UConfigCatSubsystem::GetConfigValue(const FString& Key, const UConfigCatUserWrapper* User) const
{
if (!ensure(ConfigCatClient))
{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
return {};
}

const ConfigCatUser* TargetUser = User.User.get();
const std::string& FlagKey = TCHAR_TO_UTF8(*Key);
const std::optional<Value> FeatureFlagValue = ConfigCatClient->getValue(FlagKey, User ? User->User : nullptr);

const std::shared_ptr<Value> FeatureFlagValue = ConfigCatClient->getValue(FlagKey, TargetUser);
return FConfigCatValue(FeatureFlagValue);
return UConfigCatValueWrapper::CreateValue(FeatureFlagValue);
}

FConfigCatEvaluationDetails UConfigCatSubsystem::GetBoolValueDetails(const FString& Key, bool DefaultValue, const FConfigCatUser& User) const
UConfigCatEvaluationWrapper* UConfigCatSubsystem::GetBoolValueDetails(const FString& Key, bool DefaultValue, const UConfigCatUserWrapper* User) const
{
return GetEvaluationDetails(ConfigCatClient, Key, DefaultValue, User);
}

FConfigCatEvaluationDetails UConfigCatSubsystem::GetIntValueDetails(const FString& Key, int DefaultValue, const FConfigCatUser& User) const
UConfigCatEvaluationWrapper* UConfigCatSubsystem::GetIntValueDetails(const FString& Key, int DefaultValue, const UConfigCatUserWrapper* User) const
{
return GetEvaluationDetails(ConfigCatClient, Key, DefaultValue, User);
}

FConfigCatEvaluationDetails UConfigCatSubsystem::GetDoubleValueDetails(const FString& Key, double DefaultValue, const FConfigCatUser& User) const
UConfigCatEvaluationWrapper* UConfigCatSubsystem::GetDoubleValueDetails(const FString& Key, double DefaultValue, const UConfigCatUserWrapper* User) const
{
return GetEvaluationDetails(ConfigCatClient, Key, DefaultValue, User);
}

FConfigCatEvaluationDetails UConfigCatSubsystem::GetStringValueDetails(const FString& Key, const FString& DefaultValue, const FConfigCatUser& User) const
UConfigCatEvaluationWrapper* UConfigCatSubsystem::GetStringValueDetails(const FString& Key, const FString& DefaultValue, const UConfigCatUserWrapper* User) const
{
const std::string& StringDefaultValue = TCHAR_TO_UTF8(*DefaultValue);
return GetEvaluationDetails(ConfigCatClient, Key, StringDefaultValue, User);
Expand All @@ -142,7 +140,7 @@ TArray<FString> UConfigCatSubsystem::GetAllKeys() const
return Result;
}

bool UConfigCatSubsystem::GetKeyAndValue(const FString& VariationId, FString& OutKey, FConfigCatValue& OutValue) const
bool UConfigCatSubsystem::GetKeyAndValue(const FString& VariationId, FString& OutKey, UConfigCatValueWrapper*& OutValue) const
{
if (!ensure(ConfigCatClient))
{
Expand All @@ -152,55 +150,51 @@ bool UConfigCatSubsystem::GetKeyAndValue(const FString& VariationId, FString& Ou

const std::string& VariationIdString = TCHAR_TO_UTF8(*VariationId);

std::shared_ptr<KeyValue> KeyValue = ConfigCatClient->getKeyAndValue(VariationIdString);
std::optional<KeyValue> KeyValue = ConfigCatClient->getKeyAndValue(VariationIdString);

if (!KeyValue)
{
return false;
}

OutKey = UTF8_TO_TCHAR(KeyValue->key.c_str());
OutValue = KeyValue->value;
OutValue = UConfigCatValueWrapper::CreateValue(KeyValue->value);
return true;
}

TMap<FString, FConfigCatValue> UConfigCatSubsystem::GetAllValues(const FConfigCatUser& User) const
TMap<FString, UConfigCatValueWrapper*> UConfigCatSubsystem::GetAllValues(const UConfigCatUserWrapper* User) const
{
if (!ensure(ConfigCatClient))
{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
return {};
}

const ConfigCatUser* TargetUser = User.User.get();
const std::unordered_map<std::string, Value> Values = ConfigCatClient->getAllValues(User ? User->User : nullptr);

const std::unordered_map<std::string, Value> Values = ConfigCatClient->getAllValues(TargetUser);

TMap<FString, FConfigCatValue> Result;
TMap<FString, UConfigCatValueWrapper*> Result;
for (const std::pair<const std::string, Value>& Value : Values)
{
Result.Emplace(UTF8_TO_TCHAR(Value.first.c_str()), Value.second);
Result.Emplace(UTF8_TO_TCHAR(Value.first.c_str()), UConfigCatValueWrapper::CreateValue(Value.second));
}

return Result;
}

TArray<FConfigCatEvaluationDetails> UConfigCatSubsystem::GetAllValueDetails(const FConfigCatUser& User) const
TArray<UConfigCatEvaluationWrapper*> UConfigCatSubsystem::GetAllValueDetails(const UConfigCatUserWrapper* User) const
{
if (!ensure(ConfigCatClient))
{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
return {};
}

const ConfigCatUser* TargetUser = User.User.get();

const std::vector<EvaluationDetails> ValueDetails = ConfigCatClient->getAllValueDetails(TargetUser);
const std::vector<EvaluationDetails<Value>> ValueDetails = ConfigCatClient->getAllValueDetails(User ? User->User : nullptr);

TArray<FConfigCatEvaluationDetails> Result;
for (const EvaluationDetails& ValueDetail : ValueDetails)
TArray<UConfigCatEvaluationWrapper*> Result;
for (const EvaluationDetails<Value>& ValueDetail : ValueDetails)
{
Result.Emplace(ValueDetail);
Result.Emplace(UConfigCatEvaluationWrapper::CreateEvaluation(ValueDetail));
}

return Result;
Expand All @@ -217,20 +211,20 @@ void UConfigCatSubsystem::ForceRefresh()
ConfigCatClient->forceRefresh();
}

void UConfigCatSubsystem::SetDefaultUser(const FConfigCatUser& User)
void UConfigCatSubsystem::SetDefaultUser(const UConfigCatUserWrapper* User)
{
if (!ensure(ConfigCatClient))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please create an EnsureConfigCatClient() function where this log message can be printed:

bool EnsureConfigCatCline()
{
	if (ensure(ConfigCatClient))
	{
                return true;
        }
        
	UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
	return false;
}

In every function we can use this EnsureConfigCatClient() to check the client easier:

if (!EnsureConfigCatClient())
{
        return;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a great idea. I added it now, thanks.

{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to access the ConfigCatClient before initialization or after shutdown."));
return;
}
if (!User.User)
if (!User || !User->User)
{
UE_LOG(LogConfigCat, Warning, TEXT("Trying to set Default User with invalid pointer."));
return;
}

ConfigCatClient->setDefaultUser(User.User);
ConfigCatClient->setDefaultUser(User->User);
}

void UConfigCatSubsystem::ClearDefaultUser()
Expand Down Expand Up @@ -284,7 +278,7 @@ void UConfigCatSubsystem::Initialize(FSubsystemCollectionBase& Collection)
#endif

const UConfigCatSettings* ConfigCatSettings = GetDefault<UConfigCatSettings>();
if(!ConfigCatSettings || ConfigCatSettings->SdkKey.IsEmpty())
if (!ConfigCatSettings || ConfigCatSettings->SdkKey.IsEmpty())
{
UE_LOG(LogConfigCat, Warning, TEXT("Empty SdkKey detected. Please set your SdkKey in the Project Settings."));
return;
Expand Down Expand Up @@ -371,16 +365,17 @@ void UConfigCatSubsystem::SetupClientHooks(ConfigCatOptions& Options)
TWeakObjectPtr<UConfigCatSubsystem> WeakThis(this);

Options.hooks->addOnError(
[WeakThis](const std::string& Error)
[WeakThis](const std::string& Error, const std::exception_ptr& Exception)
{
if (WeakThis.IsValid())
{
const FString& StringError = UTF8_TO_TCHAR(Error.c_str());
const FString& StringException = UTF8_TO_TCHAR(unwrap_exception_message(Exception).c_str());

UE_LOG(LogConfigCat, Error, TEXT("ConfigCatClient Error: %s"), *StringError);
UE_LOG(LogConfigCat, Error, TEXT("ConfigCatClient Error: %s Exception: %s"), *StringError, *StringException);

WeakThis->OnError.Broadcast(StringError);
WeakThis->OnErrorBp.Broadcast(StringError);
WeakThis->OnError.Broadcast(StringError, StringException);
WeakThis->OnErrorBp.Broadcast(StringError, StringException);
}
}
);
Expand All @@ -395,29 +390,24 @@ void UConfigCatSubsystem::SetupClientHooks(ConfigCatOptions& Options)
}
);
Options.hooks->addOnConfigChanged(
[WeakThis](const std::shared_ptr<Settings>& Config)
[WeakThis](const std::shared_ptr<const Settings>& InConfig)
{
if (WeakThis.IsValid())
{
FConfigCatConfig NewConfig;
if (Config)
{
for (const std::pair<const std::string, Setting>& Setting : *Config)
{
NewConfig.Settings.Emplace(UTF8_TO_TCHAR(Setting.first.c_str()), Setting.second);
}
}

WeakThis->OnConfigChanged.Broadcast(NewConfig);
WeakThis->OnConfigChangedBp.Broadcast(NewConfig);
UConfigCatSettingsWrapper* Config = UConfigCatSettingsWrapper::CreateSettings(InConfig);

WeakThis->OnConfigChanged.Broadcast(Config);
WeakThis->OnConfigChangedBp.Broadcast(Config);
}
}
);
Options.hooks->addOnFlagEvaluated(
[WeakThis](const EvaluationDetails& EvaluationDetails)
[WeakThis](const EvaluationDetailsBase& InEvaluationDetails)
{
if (WeakThis.IsValid())
{
UConfigCatEvaluationWrapper* EvaluationDetails = UConfigCatEvaluationWrapper::CreateEvaluation(InEvaluationDetails);

WeakThis->OnFlagEvaluated.Broadcast(EvaluationDetails);
WeakThis->OnFlagEvaluatedBp.Broadcast(EvaluationDetails);
}
Expand Down Expand Up @@ -457,4 +447,4 @@ void UConfigCatSubsystem::SetupClientOverrides(ConfigCatOptions& Options)
// std::unordered_map<std::string, Value> OverrideFlags;
// Options.flagOverrides = std::make_shared<MapFlagOverrides>(OverrideFlags, Behaviour);
}
}
}
Loading
Loading