diff --git a/Source/SkyPortal/Private/SkyPortalIO.cpp b/Source/SkyPortal/Private/SkyPortalIO.cpp index 32152e0..4aad7d4 100644 --- a/Source/SkyPortal/Private/SkyPortalIO.cpp +++ b/Source/SkyPortal/Private/SkyPortalIO.cpp @@ -164,11 +164,20 @@ void USkyPortalIO::WriteRaw(const TArray* block) uint8* USkyPortalIO::Read() { - uint8* output = new byte[0x20]; - if (hid_read(PortalDevice, output, 0x20) == -1) { - UE_LOG(LogSkyportalIO, Error, TEXT("Unable to read data from Portal. error:\n %s"), hid_error(PortalDevice)); - return 0; - }; + uint8* output = new uint8[0x20]; + int result = hid_read(PortalDevice, output, 0x20); + + if (result == -1) { + UE_LOG(LogSkyportalIO, Error, TEXT("Unable to read data from Portal. Error:\n%s"), hid_error(PortalDevice)); + delete[] output; // Prevent memory leak + return nullptr; + } + + if (result == 0) { // No data was read + UE_LOG(LogSkyportalIO, Warning, TEXT("No data read from portal")); + delete[] output; + return nullptr; + } return output; } @@ -180,24 +189,22 @@ uint8* USkyPortalIO::QueryBlock(uint8 FigureIndex, uint8 BlockIndex) command.data[1] = 'Q'; command.data[2] = FigureIndex; // Figure index (0x00-0x0F) command.data[3] = BlockIndex; - unsigned char* output; + unsigned char* output = nullptr; int attempt=0; do { attempt++; UE_LOG(LogSkyportalIO, Verbose, TEXT("Trying to write... attempt:%d"), attempt); if (Write(&command)) { output = Read(); - if (output == 0) { - UE_LOG(LogSkyportalIO, Error, TEXT("Something went wrong"), attempt); + if (output != 0) { + UE_LOG(LogSkyportalIO, Verbose, TEXT("Read success: output[0]=%d, output[1]=%d, output[2]=%d"), output[0], output[1], output[2]); + }else{ + UE_LOG(LogSkyportalIO, Error, TEXT("Read failed, output is null")); return 0; } } - else { - UE_LOG(LogSkyportalIO, Error, TEXT("Something went wrong"), attempt); - return 0; - } - } while (output[0] != 'Q' || (output[1] % 0x10 != FigureIndex && output[1] != 0x01) || output[2] != BlockIndex|| attempt <10); + } while ((output[0] != 'Q' || (output[1] % 0x10 != FigureIndex && output[1] != 0x01) || output[2] != BlockIndex) && attempt < 10); UE_LOG(LogSkyportalIO, Verbose, TEXT("Querying block %d - success"), BlockIndex); UE_LOG(LogSkyportalIO, VeryVerbose, TEXT("Data block %d = \n %s"), BlockIndex,*OutputToString(output)); return output; diff --git a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp index fb3124c..a9910b9 100644 --- a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp +++ b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp @@ -251,13 +251,34 @@ bool USkyPortalSubsystem::IsPortalReady() return; } - void USkyPortalSubsystem::PortalAnalyze(const uint8 index) +void USkyPortalSubsystem::PortalAnalyzeAsync(const uint8 Index) { bShouldPauseRunner = true; + UE_LOG(LogSkyportalIO, Log, TEXT("Starting async figure analysis...")); + + // Run the PortalAnalyze function asynchronously on a background thread + AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this, Index]() + { + // Perform the blocking operation on the background thread + PortalAnalyze(Index); + + // Once done, switch back to the main game thread + AsyncTask(ENamedThreads::GameThread, [this, Index]() + { + // This will be executed on the game thread after the async task is complete + bShouldPauseRunner = false; + UE_LOG(LogSkyportalIO, Log, TEXT("Figure analysis complete for index: %d"), Index); + }); + }); + } + + void USkyPortalSubsystem::PortalAnalyze(const uint8 index) + { + UE_LOG(LogSkyportalIO, Log, TEXT("Reading figure...")); FigureArray[index] = PortalHandle->ReadFigureBlocks(index); UE_LOG(LogSkyportalIO, Log, TEXT("Figure ID : %d"), FigureArray[index].GetFigureID()); - bShouldPauseRunner = false; + } void USkyPortalSubsystem::GetFigureArray() { diff --git a/Source/SkyPortal/Public/SkyPortalSubsystem.h b/Source/SkyPortal/Public/SkyPortalSubsystem.h index b9b51d4..275beb0 100644 --- a/Source/SkyPortal/Public/SkyPortalSubsystem.h +++ b/Source/SkyPortal/Public/SkyPortalSubsystem.h @@ -82,7 +82,7 @@ public: SKYPORTAL_API void PortalMusic(const USoundWave* Sound); UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|Figure|Debug")) - SKYPORTAL_API void PortalAnalyze(const uint8 index); + SKYPORTAL_API void PortalAnalyzeAsync(const uint8 index); UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|Commands|Figure")) SKYPORTAL_API void GetFigureArray(); @@ -155,6 +155,8 @@ private: */ static void Sleep(int sleepMs); + void PortalAnalyze(const uint8 Index); + // Pointer to the status checker thread FPortalStatusChecker* StatusChecker; FRunnableThread* StatusCheckerThread;