x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Avoid blocking game thread when saving file.

I'm working on a gearvr app and trying to download an mp4 (aprox 250mb) and save it to the device.

It seems the save operation blocks the game thread, which causes the rendering to freeze for a few seconds, while the gearvr IMU remains active. The result is that the game freezes and you basically end up being able to look around a frozen quad :/

My download and save code is:

 request->OnProcessRequestComplete().BindLambda([&](FHttpRequestPtr request, FHttpResponsePtr response, bool success) {
         if (!success) {
             return;
         }
 
         TArray<uint8> data = response->GetContent();
         FString path = FPaths::Combine(FPaths::GamePersistentDownloadDir(), "video.mp4");
         FBufferArchive archive;
         archive << data;
 
         success = FFileHelper::SaveArrayToFile(archive, *path);
 
         if (success) {
             UGameplayStatics::OpenLevel(GetWorld(), "Player");
         }
     });

Since the downloading operation itself does not seem to be the one blocking the UI, I assume it would be either the insertion operator archive << data or SaveArrayToFile. So I tried doing both operations on a separate thread, like so:

 ACard::ACard() {
     PrimaryActorTick.bCanEverTick = true;
     
     // ...
     
     request->OnProcessRequestComplete().BindLambda([&](FHttpRequestPtr request, FHttpResponsePtr response, bool success) {
         GEngine->AddOnScreenDebugMessage(-1, 2.f,
             success ? FColor::Green : FColor::Red,
             success ? TEXT("download successful") : TEXT("download failed"));
 
         if (!success) {
             return;
         }
 
         task = Task::dispatch([response]() {
             FBufferArchive archive;
             TArray<uint8> data = response->GetContent();
             archive << data;
 
             FString path = FPaths::Combine(FPaths::GamePersistentDownloadDir(), "video.mp4");
             FFileHelper::SaveArrayToFile(archive, *path);
         });
 
         SetActorTickEnabled(true);
     });
 }
 
 void ACard::BeginPlay() {
     Super::BeginPlay();
     SetActorTickEnabled(false);
 }
 
 void ACard::Tick( float DeltaTime ) {
     Super::Tick( DeltaTime );
 
     if (task && task->complete) {
         SetActorTickEnabled(false);
         UGameplayStatics::OpenLevel(GetWorld(), "Player");
     }
 }

Where Task is defined like so:

 class  Task : public FRunnable {
 
 private:
     TFunction<void()> task;
     FRunnableThread* thread;
 
 public:
     bool complete{ false };
 
     static Task* dispatch(TFunction<void()> task) {
         auto newInstance = new Task(task);
 
         newInstance->thread = FRunnableThread::Create(
             newInstance,
             TEXT(""),
             0,
             TPri_BelowNormal
         );
 
         return newInstance;
     }
 
     Task(TFunction<void()> task) : task(task) {}
     bool Init() override { return true; }
     void Stop() override {}
 
     uint32 Run() override {
         task();
         complete = true;
         return 0;
     }
 };

But the above seems to make no difference: Saving the file still blocks the UI for about 3secs. So my question is: how should I be saving the file to storage without blocking the game itself?

UPDATE:

This issue is still not resolved. Following the advice in one of the comments below, I added logs to check that the code does indeed execute on separate threads and it does. The logs are consistent with the actions:

  1. Dispatch save task from game thread.

  2. execute task (save) in background thread.

  3. dispatch new task to load the next level from background thread.

  4. execute new task (load next level) from game thread.

Yet the UI thread still blocks.

 01 - 18 19:59 : 10.404 18059 18075 D UE4 : LogTemp:Warning: Dispatch TASK : tID 18075 | is game ? 1
 01 - 18 19 : 59 : 10.404 18059 18075 D UE4 : [2017.01.19 - 00.59.10:415][-8608252]LogTemp : Warning : Dispatch TASK : tID 18075 | is game ? 1
 01 - 18 19 : 59 : 10.414 18059 18259 D UE4 : LogTemp:Warning: Execute TASK : tID 18259 | is game ? 0
 01 - 18 19 : 59 : 10.414 18059 18075 D UE4 : [2017.01.19 - 00.59.10:419][-8608252]LogTemp : Warning : Execute TASK : tID 18259 | is game ? 0
 01 - 18 19 : 59 : 10.524 18059 18140 I OVR : PhoneManagerThread - phone running!nfds = 1
 01 - 18 19 : 59 : 10.524 18059 18259 D UE4 : LogTemp:Warning: Dispatch TASK : tID 18259 | is game ? 0
 01 - 18 19 : 59 : 10.524 18059 18075 D UE4 : [2017.01.19 - 00.59.10:536][-8608252]LogTemp : Warning : Dispatch TASK : tID 18259 | is game ? 0
 01 - 18 19 : 59 : 11.064 18059 18075 D UE4 : LogTemp:Warning: Execute TASK : tID 18075 | is game ? 1
 01 - 18 19 : 59 : 11.064 18059 18075 D UE4 : [2017.01.19 - 00.59.11:072][-8608252]LogTemp : Warning : Execute TASK : tID 18075 | is game ? 1



Product Version: UE 4.14
Tags:
more ▼

asked Dec 05 '16 at 03:17 AM in C++ Programming

avatar image

saldavonschwartz
157 16 19 35

avatar image saldavonschwartz Jan 19 '17 at 01:16 AM

bump. Someone, please? :(

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question