FRunnable Callback Issue

  • Hi, I have a Json data string which I have to process which comes from making a HTTP request.
  • I’ve created a

FRunnable

thread class to handle the processing of this data.

  • I’ve added a

DECLARE_DELEGATE(FJsonRead);

in the thread class.

  • Here is the FRunnable Class headersand cpp.
  • Notice the

JsonRead

in the thread class. On no. 101 in cpp file section I wrote


void FCoalaReadJsonAsync::JsonToCoalaArea(FString JsonRaw, int defaultBuildingLevel, bool clampToDefaultBuildingLevel, int limitMaxBuildingLevelTo, UCoalaArea* _result)
	{

	   FCoalaReadJsonAsync::JsonToCoalaArea(*JsonRaw, defaultBuildingLevel, clampToDefaultBuildingLevel, limitMaxBuildingLevelTo, true, _result);

	   isDone = true;
	   JsonRead.Execute();
	}

  • I’ve binded a UFUNCTION in my Mapbase class with the function

void ASWPMapBase::PrintJsonString()
	{
	   UE_LOG(LogFlying, Warning, TEXT("Json Reading is done "));
	}

	

My question is :
Can I add a delegate in the Thread class to get to know when its processing is done ? I tried the same by calling the on the mentioned line number above.

Here is how I’m calling the thread function:


void ASWPMapBase::PrintTheString(FString str)
{
    UE_LOG(LogFlying, Warning, TEXT("Printing SUCCESS: "));

    UCoalaArea* ret = NewObject<UCoalaArea>();
    ret->AddToRoot();

   FCoalaReadJsonAsync* RunnableThread = FCoalaReadJsonAsync::JoyInit(str, 3, true, 0, ret);
   RunnableThread->JsonRead.BindUFunction(this, "PrintJsonString");
}

And here is the response log I’m getting:


LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Json Reading is done
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:
LogFlying: Warning: Printing SUCCESS:

**AS YOU SEE THE THREAD IS CALLING JSON READ DONE ONLY ONCE BUT I CALLED THE THREAD SO MANY TIMES!

HOW CAN I GET THE FUNCTION CALL BACK FROM THREAD IN ANOTHER ACTOR CLASS ?**

the issue is your on a different thread, you need to call the delegate on the gamethread,


  
 AsyncTask(ENamedThreads::GameThread,
        [this]() {  JsonRead.Execute(); });


might work?

@KaosSpectrum could you elaborate more ? Shall I add my delegate Execute() somewhere else ? Am I missing any thread function to add to keep things in check ?

Basically you need to sync your delegate call with the game thread, everything you do inside the FRunnable is a different thread and if you modify game information you can potentially crash. The function provided by KaosSpectrum in will be use to sync your delegate call in your case, AsyncTask ask for 3 parameters, first one is the thread where your code will be executed, the second is a ref of the class and the third is the body, this function is kinda a lamda-ish function. As you can see kaosSpectrum is calling your delegate from within the body of the AsynTask function.

Hope that make it clear