dirkFist
(dirkFist)
August 29, 2019, 1:17am
1
Pending action class
class myPendingLatentAction: public FPendingLatentAction {
public:
TSharedPtr<IHttpRequest> Request;
FLatentActionInfo info;
TSharedPtr<FString> result = MakeShareable<FString>(new FString(TEXT("")));
bool complete = false;
bool success = false;
myPendingLatentAction(TSharedPtr<IHttpRequest> Request, FLatentActionInfo info) : Request(Request), info(info)
{}
virtual void UpdateOperation(FLatentResponse& Update) override
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Complete ---------"));
Update.FinishAndTriggerIf(complete, info.ExecutionFunction, info.Linkage, info.CallbackTarget);
}
};
Latent function
bool Ujson2structBPLibrary::TestUrlLatent(FString URL, FString JSON, FString& result, FLatentActionInfo info, UObject* WC)
{
UWorld * World = GEngine->GetWorldFromContextObject(WC); //TODO deprecated lookup replacement
if (!World) { return false; }
FLatentActionManager& LatentManager = World->GetLatentActionManager();
FHttpModule* Http = &FHttpModule::Get();
TSharedPtr<IHttpRequest> Request = Http->CreateRequest();
myPendingLatentAction* RequestAction = new myPendingLatentAction(Request, info);
if (LatentManager.FindExistingAction<myPendingLatentAction>(info.CallbackTarget, info.UUID) != NULL) { return false; }
LatentManager.AddNewAction(info.CallbackTarget, info.UUID, RequestAction);
Request->SetURL(URL);
Request->SetVerb("GET");
Request->SetContentAsString(JSON);
Request->SetHeader("User-Agent", "X-UrealEngine-Agent");
Request->SetHeader("Content-Type", "application/json");
Request->SetHeader("Accept", "application/json");
Request->OnProcessRequestComplete().BindLambda(
[&RequestAction,&result](FHttpRequestPtr request, FHttpResponsePtr response, bool success)
{
if (success)
{
auto temp = response->GetContentAsString();
//This part displays the http response if the next bit is commented
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, temp);
// this compiles but throws an exception
RequestAction->result->Append(temp);
}
RequestAction->success = success;
RequestAction->complete = true;
}
);
Request->ProcessRequest();
return true;
}
dirkFist
(dirkFist)
August 29, 2019, 3:23pm
2
Looks like myPendingLatentAction gets destroyed before the handler is called. Which is odd because myPendingLatentAction is dynamically allocated with new so it should be on the heap requiring an explicit deallocation. Every NEW requires delete I’ve tried making it a shared pointer and so forth.
dirkFist
(dirkFist)
August 29, 2019, 3:29pm
3
This version of myPendingLatentAction displays “me is null”
class myPendingLatentAction: public FPendingLatentAction {
public:
TSharedPtr<IHttpRequest> Request;
FLatentActionInfo info;
FString& result;
bool complete = false;
bool success = false;
myPendingLatentAction(TSharedPtr<IHttpRequest> Request, FLatentActionInfo info, FString& result) : Request(Request), info(info), result(result)
{}
virtual void UpdateOperation(FLatentResponse& Update) override
{
if (complete) {
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Complete ---------"));
Update.FinishAndTriggerIf(complete, info.ExecutionFunction, info.Linkage, info.CallbackTarget);
Update.DoneIf(complete);
}
}
static void responseHandler(myPendingLatentAction* me, FHttpRequestPtr request, FHttpResponsePtr response, bool success)
{
if (me == nullptr)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("me is null"));
}
}
};
dirkFist
(dirkFist)
August 29, 2019, 3:31pm
4
Displays “this is null”
class myPendingLatentAction: public FPendingLatentAction {
...
void responseHandler(FHttpRequestPtr request, FHttpResponsePtr response, bool success)
{
if (this == nullptr)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("this is null"));
}
}
};
dirkFist
(dirkFist)
August 29, 2019, 3:59pm
5
Changed my Lambda set up to grab the object as pointer rather a reference
bool Ujson2structBPLibrary::TestUrlLatent(FString URL, FString JSON, FString& result, FLatentActionInfo info, UObject* WC)
{
result = *(new FString(L"WHY"));
UWorld * World = GEngine->GetWorldFromContextObject(WC, EGetWorldErrorMode::ReturnNull);
if (!World) { return false; }
FLatentActionManager& LatentManager = World->GetLatentActionManager();
FHttpModule* Http = &FHttpModule::Get();
TSharedPtr<IHttpRequest> Request = Http->CreateRequest();
if (LatentManager.FindExistingAction<myPendingLatentAction>(info.CallbackTarget, info.UUID) != NULL) { return false; }
myPendingLatentAction* RequestAction = new myPendingLatentAction(Request,info,result);
LatentManager.AddNewAction(info.CallbackTarget, info.UUID, RequestAction);
Request->SetURL(URL);
Request->SetVerb("GET");
Request->SetContentAsString(JSON);
Request->SetHeader("User-Agent", "X-UrealEngine-Agent");
Request->SetHeader("Content-Type", "application/json");
Request->SetHeader("Accept", "application/json");
Request->OnProcessRequestComplete().BindLambda(
[RequestAction](FHttpRequestPtr request, FHttpResponsePtr response, bool success)
{
myPendingLatentAction::responseHandler(RequestAction,request, response, success);
}
);
Request->ProcessRequest();
return true;
}