Hello guys!
I’ve been working for some time now, on adding Leaderboard functions to my project and i did that. However as you may know those functions return asynchronusly, which is little problematic to handle. For now i have dispatchers, that are just broadcasting when leaderboard handle is returned but i really would love to have it working with latent class.
For now my code is doing this:
1.Send call for “name” leaderboard. This function is called FindLeaderboard() in Steamworks.
2.Add new action to latent action manager.
3.Call OnFindLeaderboard() function which is callback for FindLeaderboard() inside MyLatentClass.
4.It is getting in OnFindLeaderboard() function, coming back to MyLatentClass and waiting forever.
It seems for me that, when i call OnFindLeaderboard form MyLatentClass instead of USteamLeaderboard, it never sets the handle in this line:
m_CurrentLeaderboard = pCallback->m_hSteamLeaderboard;
and even broadcast line below is never working.
Here is my code of all used methods in this case:
FindLeaderboard that i use atm
void USteamLeaderboard::FindLeaderboardLatent(FString StatName, struct FLatentActionInfo LatentInfo, float duration, UObject* WorldContextObject)
{
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject))
{
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
if (LatentActionManager.FindExistingAction<MyLatentClass>(LatentInfo.CallbackTarget, LatentInfo.UUID) == NULL)
{
if (SteamAPI_Init())
{
m_CurrentLeaderboard = NULL;
const char *LBname = TCHAR_TO_ANSI(*StatName);
//SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard(LBname);
//m_callResultFindLeaderboard.Set(hSteamAPICall,this,&USteamLeaderboard::OnFindLeaderboard);
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new MyLatentClass(duration, LatentInfo,m_callResultFindLeaderboard));
}
}
}
}
OnFindLeaderboard
//Function is called as callback for FindLeaderboard()
void USteamLeaderboard::OnFindLeaderboard(LeaderboardFindResult_t *pCallback, bool bIOFailure)
{
// see if we encountered an error during the call
if (!pCallback->m_bLeaderboardFound || bIOFailure)
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("Leaderboard could not be found"));
OnFindSteamLeaderboard.Broadcast(false);
return;
}
m_CurrentLeaderboard = pCallback->m_hSteamLeaderboard;
OnFindSteamLeaderboard.Broadcast(true);
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("I'm in OnFindLeaderboard"));
return;
}
MyLatentClass.cpp
MyLatentClass::MyLatentClass(float Duration, const FLatentActionInfo& LatentInfo, CCallResult <USteamLeaderboard, LeaderboardFindResult_t> m_callResultFindLeaderboard)
: TimeRemaining(Duration)
, ExecutionFunction(LatentInfo.ExecutionFunction)
, OutputLink(LatentInfo.Linkage)
, CallbackTarget(LatentInfo.CallbackTarget)
, CallFindLeaderboard(m_callResultFindLeaderboard)
{
}
MyLatentClass::~MyLatentClass()
{
}
And finally my latent class.h
class PROJECT_API MyLatentClass : public FPendingLatentAction
{
public:
float TimeRemaining;
FName ExecutionFunction;
int32 OutputLink;
bool asdf = false;
FWeakObjectPtr CallbackTarget;
SteamLeaderboard_t m_CurrentLeaderboard;
CCallResult <USteamLeaderboard, LeaderboardFindResult_t> CallFindLeaderboard;
MyLatentClass(float Duration, const FLatentActionInfo& LatentInfo, CCallResult <USteamLeaderboard, LeaderboardFindResult_t> m_callResultFindLeaderboard);
~MyLatentClass();
virtual void UpdateOperation(FLatentResponse& Response) override
{
USteamLeaderboard *obj = NewObject<USteamLeaderboard>();
while (asdf == false)
{
SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard("test");
CallFindLeaderboard.Set(hSteamAPICall,obj, &USteamLeaderboard::OnFindLeaderboard);
asdf = true;
}
//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("Waiting"));
//Response.DoneIf(isHandleSet());
while (isHandleSet() && TimeRemaining > 0)
{
TimeRemaining -= Response.ElapsedTime();
}
Response.FinishAndTriggerIf(TimeRemaining <= 0.0f, ExecutionFunction, OutputLink, CallbackTarget);
}
bool isHandleSet()
{
USteamLeaderboard *obj = NewObject<USteamLeaderboard>();
if (&USteamLeaderboard::m_CurrentLeaderboard)
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("no tru"));
return true;
}
else
{
//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("czemu fols"));
return false;
}
}
I am really confused, caused to crash engine many times. If anoyone can explain me why this is not working it would be great.