Cleaned up includes
This commit is contained in:
parent
117da9d24a
commit
b959059755
10 changed files with 175 additions and 232 deletions
|
@ -1,6 +1,7 @@
|
|||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "SkyPortal.h"
|
||||
#include "SkyPortalSubsystem.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FSkyPortalModule"
|
||||
|
||||
|
|
|
@ -2,20 +2,27 @@
|
|||
|
||||
#include "SkyPortalFigure.h"
|
||||
|
||||
uint32 GetFigureID(const FigureDataBlock& DataBlock)
|
||||
|
||||
uint32 FigureData::GetFigureID()
|
||||
{
|
||||
int16_t OutFigureID;
|
||||
// Figure ID is stored in Block 0, bytes 0 to 3 (32-bit integer, little-endian)
|
||||
OutFigureID = DataBlock.blockdata[0][0] |
|
||||
(DataBlock.blockdata[0][1] << 8) |
|
||||
(DataBlock.blockdata[0][2] << 16) |
|
||||
(DataBlock.blockdata[0][3] << 24);
|
||||
if (ID == 0) {
|
||||
int16_t OutFigureID = 0;
|
||||
|
||||
// The figure ID is stored in Block 1 of Sector 0 (i.e., data[1]), bytes 0 and 1 (16-bit integer, little-endian)
|
||||
OutFigureID = data[1][0] | // Least significant byte
|
||||
(data[1][1] << 8); // Most significant byte, shifted left by 8 bits
|
||||
|
||||
ID = OutFigureID;// Return the 16-bit figure ID
|
||||
return OutFigureID;
|
||||
}
|
||||
else { return ID; }
|
||||
/*
|
||||
// Variant ID is stored in Block 0, bytes 4 to 5 (16-bit integer, little-endian)
|
||||
OutVariantID = (DataBlock.blockdata[0][5] << 8) |
|
||||
DataBlock.blockdata[0][4];
|
||||
*/
|
||||
return OutFigureID;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -263,3 +263,58 @@ FPortalStatusData ParsePortalStatus(const uint8* StatusResponse)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
|
||||
{
|
||||
|
||||
FigureData FigureData;
|
||||
FigureData.dataError = false; // Initialize error flag
|
||||
|
||||
FWriteBlock command;
|
||||
|
||||
// Loop over all 64 blocks
|
||||
for (uint8 BlockIndex = 0; BlockIndex < FIGURE_TOTAL_BLOCKS; ++BlockIndex)
|
||||
{
|
||||
memset(command.data, 0, write_buf_size); //maybe not needed here
|
||||
command.data[1] = 'Q';
|
||||
command.data[2] = FigureIndex; // Figure index (0x00-0x0F)
|
||||
command.data[3] = BlockIndex;
|
||||
uint8* output;
|
||||
do {
|
||||
Write(&command);
|
||||
output = Read();
|
||||
} while (output[0] != 'Q');
|
||||
|
||||
if (output[1] == (0x10 + 'Q')) // Successful query
|
||||
{
|
||||
// Extract the 16 bytes of block data
|
||||
for (int i = 3; i < 19; i++)
|
||||
{
|
||||
FigureData.data[BlockIndex][i] = output[i];
|
||||
}
|
||||
}
|
||||
else if (output[0] == 0x01) {
|
||||
FigureData.dataError = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Error querying block %d from figure %d"), BlockIndex, FigureIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Verify that the block index matches the requested block
|
||||
uint8 ReturnedBlockIndex = output[3];
|
||||
if (ReturnedBlockIndex != BlockIndex)
|
||||
{
|
||||
FigureData.dataError = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Mismatched block index. Expected %d, got %d"), BlockIndex, ReturnedBlockIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy block data into FigureData
|
||||
//memcpy(FigureData.blockdata[BlockIndex], &res.buf[4], FIGURE_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
// Some verifications should happen. Like if dataError is set.
|
||||
|
||||
return FigureData; // Return the complete figure data
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ void FPortalStatusChecker::CheckPortalStatus()
|
|||
// Call the subsystem function to get portal status
|
||||
uint8* output = PortalHandleRef->Read();
|
||||
EPortalCommand CommandResponse = GetPortalCommandFromChar(output[0]);
|
||||
FigureData figData;
|
||||
switch (CommandResponse)
|
||||
{
|
||||
case S:
|
||||
|
@ -71,15 +72,15 @@ void FPortalStatusChecker::CheckPortalStatus()
|
|||
switch (CurrentStatusData.StatusArray[i])
|
||||
{
|
||||
case EFigureStatus::NOT_PRESENT:
|
||||
subref->OnSkylanderRemoved.Broadcast(00, i);
|
||||
|
||||
break;
|
||||
case EFigureStatus::PRESENT:
|
||||
//FigureData = ReadFigureBlocks(i);
|
||||
//subref->OnSkylanderAdded.Broadcast(GetFigureID(FigureData), i);
|
||||
break;
|
||||
case EFigureStatus::ADDED:
|
||||
//FigureData = ReadFigureBlocks(i);
|
||||
//subref->OnSkylanderAdded.Broadcast(GetFigureID(FigureData), i);
|
||||
figData = PortalHandleRef->ReadFigureBlocks(i);
|
||||
subref->OnSkylanderAdded.Broadcast(figData.GetFigureID(), i);
|
||||
break;
|
||||
case EFigureStatus::REMOVED:
|
||||
subref->OnSkylanderRemoved.Broadcast(00, i);
|
||||
|
|
|
@ -75,8 +75,12 @@ void USkyPortalSubsystem::PortalReady()
|
|||
output = PortalHandle->Read();
|
||||
} while (output[0] != 'R');
|
||||
|
||||
uint16 _PortalId = ((output[1] << 8) + output[2]);
|
||||
PortalId = _PortalId; //Need a conversion as uint16 is not supported in BP
|
||||
unsigned char _PortalId[2] = { output[1],output[2] };
|
||||
int32 BE_PortalId = (_PortalId[0] << 8) | _PortalId[1]; // Big-endian format
|
||||
uint32 BEU_PortalId = (_PortalId[0] << 8) | _PortalId[1]; // Big-endian format unsigned
|
||||
int32 LE_PortalId = (_PortalId[1] << 8) | _PortalId[0]; //little endian
|
||||
uint32 LEU_PortalId = (_PortalId[1] << 8) | _PortalId[0]; //little endian unsigned
|
||||
PortalId = LE_PortalId; //Need a conversion as uint16 is not supported in BP
|
||||
|
||||
}
|
||||
|
||||
|
@ -181,60 +185,6 @@ void USkyPortalSubsystem::ChangePortalColorSide(const FLinearColor& Color, const
|
|||
|
||||
|
||||
|
||||
|
||||
FPortalStatusData USkyPortalSubsystem::OLDParsePortalStatus(const FWriteBlock& ResponseBlock)
|
||||
{
|
||||
FPortalStatusData PortalStatusData;
|
||||
|
||||
// Parse the figure status array (little-endian 32-bit integer)
|
||||
uint32 FigureStatusArray = 0;
|
||||
// Reading the 32-bit integer (character status array) from the buffer
|
||||
FigureStatusArray |= ResponseBlock.data[1]; // 1st byte
|
||||
FigureStatusArray |= (ResponseBlock.data[2] << 8); // 2nd byte
|
||||
FigureStatusArray |= (ResponseBlock.data[3] << 16); // 3rd byte
|
||||
FigureStatusArray |= (ResponseBlock.data[4] << 24); // 4th byte
|
||||
|
||||
TStaticArray<EFigureStatus, 16> tempArray;
|
||||
// For each of the 16 entries, extract the 2-bit status and map it to EFigureStatus
|
||||
for (int32 i = 0; i < 16; ++i)
|
||||
{
|
||||
uint8 StatusBits = (FigureStatusArray >> (i * 2)) & 0b11; // Extract 2 bits
|
||||
EFigureStatus FigureStatus;
|
||||
|
||||
switch (StatusBits)
|
||||
{
|
||||
case 0b00:
|
||||
FigureStatus = EFigureStatus::NOT_PRESENT;
|
||||
break;
|
||||
case 0b01:
|
||||
FigureStatus = EFigureStatus::PRESENT;
|
||||
break;
|
||||
case 0b11:
|
||||
FigureStatus = EFigureStatus::ADDED;
|
||||
break;
|
||||
case 0b10:
|
||||
FigureStatus = EFigureStatus::REMOVED;
|
||||
break;
|
||||
default:
|
||||
FigureStatus = EFigureStatus::NOT_PRESENT; // Default case
|
||||
break;
|
||||
}
|
||||
|
||||
// Add to the array of figure statuses
|
||||
//PortalStatusData.StatusArray.Insert(FigureStatus, i);
|
||||
tempArray[i] = FigureStatus;
|
||||
}
|
||||
PortalStatusData.StatusArray.SetNum(0);
|
||||
PortalStatusData.StatusArray.Append(tempArray);
|
||||
// The next byte is the response counter
|
||||
PortalStatusData.Counter = ResponseBlock.data[5];
|
||||
|
||||
// The last byte is the boolean indicating whether the portal is ready
|
||||
PortalStatusData.bIsReady = ResponseBlock.data[6] != 0; // 0 means not ready, non-zero means ready
|
||||
|
||||
return PortalStatusData;
|
||||
}
|
||||
|
||||
void USkyPortalSubsystem::Sleep(int sleepMs) {
|
||||
FPlatformProcess::Sleep(sleepMs * 0.0001);
|
||||
}
|
||||
|
@ -268,69 +218,3 @@ SKYPORTAL_API void USkyPortalSubsystem::PortalMusic(const USoundWave* Sound)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FigureDataBlock USkyPortalSubsystem::ReadFigureBlocks(uint8 FigureIndex)
|
||||
{
|
||||
FigureDataBlock FigureData;
|
||||
FigureData.error = false; // Initialize error flag
|
||||
|
||||
FWriteBlock req, res;
|
||||
|
||||
// Loop over all 64 blocks
|
||||
for (uint8 BlockIndex = 0; BlockIndex < FIGURE_TOTAL_BLOCKS; ++BlockIndex)
|
||||
{
|
||||
// Prepare the request buffer
|
||||
memset(command.data, 0, rw_buf_size);
|
||||
command.data[1] = 'Q'; // Command character
|
||||
command.data[2] = FigureIndex; // Figure index (0x00 to 0x0F)
|
||||
command.data[3] = BlockIndex; // Block index (0x00 to 0x3F)
|
||||
|
||||
// Send the request
|
||||
Write(&req);
|
||||
|
||||
// Read the response
|
||||
int BuffResponse = hid_read_timeout(PortalDevice, res.buf, rw_buf_size, TIMEOUT);
|
||||
|
||||
// Check if the response was received successfully
|
||||
if (BuffResponse < rw_buf_size)
|
||||
{
|
||||
FigureData.error = true; // Mark error flag
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Error receiving data for block %d of figure %d"), BlockIndex, FigureIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse the response status
|
||||
uint8 StatusByte = res.buf[2];
|
||||
uint8 ReturnedBlockIndex = res.buf[3];
|
||||
|
||||
// Check for errors in the status byte
|
||||
if (StatusByte == 0x01) // Error in response
|
||||
{
|
||||
FigureData.error = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Error reading block %d for figure %d"), BlockIndex, FigureIndex);
|
||||
break;
|
||||
}
|
||||
else if (StatusByte != (0x10 + 'Q')) // Unexpected status byte
|
||||
{
|
||||
FigureData.error = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Unexpected status byte 0x%02X for block %d"), StatusByte, BlockIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Verify that the block index matches the requested block
|
||||
if (ReturnedBlockIndex != BlockIndex)
|
||||
{
|
||||
FigureData.error = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Mismatched block index. Expected %d, got %d"), BlockIndex, ReturnedBlockIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy block data into FigureData
|
||||
memcpy(FigureData.blockdata[BlockIndex], &res.buf[4], FIGURE_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
return FigureData; // Return the complete figure data
|
||||
}
|
||||
*/
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
#include "SkyPortalSubsystem.h"
|
||||
|
||||
class FSkyPortalModule : public IModuleInterface
|
||||
{
|
||||
|
|
83
Source/SkyPortal/Public/SkyPortalDefinitions.h
Normal file
83
Source/SkyPortal/Public/SkyPortalDefinitions.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "SkyPortalDefinitions.generated.h"
|
||||
|
||||
// This file is not supposed to have a c++ counterpart. Use it as a library
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EFigureStatus : uint8
|
||||
{
|
||||
NOT_PRESENT = 0b00 UMETA(DisplayName = "Not Present"),
|
||||
PRESENT = 0b01 UMETA(DisplayName = "Present"),
|
||||
ADDED = 0b11 UMETA(DisplayName = "Added"),
|
||||
REMOVED = 0b10 UMETA(DisplayName = "Removed")
|
||||
};
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum EPortalSide {
|
||||
LEFT UMETA(DisplayName = "Left side"),
|
||||
RIGHT UMETA(DisplayName = "Right side"),
|
||||
BOTH UMETA(DisplayName = "Both left and right"),
|
||||
TRAP UMETA(DisplayName = "Trap")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum EPortalCommand {
|
||||
A UMETA(DisplayName = "Activate"),
|
||||
C UMETA(DisplayName = "Color"),
|
||||
J UMETA(DisplayName = "Advanced color"),
|
||||
L UMETA(DisplayName = "Trap color"),
|
||||
M UMETA(DisplayName = "Music"),
|
||||
Q UMETA(DisplayName = "Query"),
|
||||
R UMETA(DisplayName = "Ready"),
|
||||
S UMETA(DisplayName = "Status")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FPortalStatusData
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Array of statuses
|
||||
UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder))
|
||||
TArray<EFigureStatus> StatusArray;
|
||||
|
||||
// timestamp.
|
||||
// only one byte long. This means that after the value 0xFF, it overflows back to 0x00.
|
||||
// Since these are so far apart, it can be assumed that 0x00 is newer than anything in the range 0xF0 - 0xFF.
|
||||
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
|
||||
uint8 Counter;
|
||||
|
||||
// Should always be true
|
||||
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
|
||||
bool bIsReady;
|
||||
|
||||
explicit FPortalStatusData(uint8 ArraySize = 16, EFigureStatus DefaultStatus = EFigureStatus::NOT_PRESENT) :
|
||||
Counter(0),
|
||||
bIsReady(true)
|
||||
{
|
||||
// Initialisation du tableau StatusArray avec 16 éléments par défaut
|
||||
StatusArray.Init(DefaultStatus, ArraySize);
|
||||
}
|
||||
|
||||
// Overload the == operator
|
||||
// Different only between
|
||||
bool operator==(const FPortalStatusData& Other) const
|
||||
{
|
||||
if (bIsReady == Other.bIsReady && Counter == Other.Counter) {
|
||||
if (StatusArray == Other.StatusArray) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Overload the != operator
|
||||
bool operator!=(const FPortalStatusData& Other) const
|
||||
{
|
||||
return !(*this == Other);
|
||||
}
|
||||
};
|
|
@ -3,15 +3,6 @@
|
|||
//#include "SkyPortalFigure.generated.h"
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EFigureStatus : uint8
|
||||
{
|
||||
NOT_PRESENT = 0b00 UMETA(DisplayName = "Not Present"),
|
||||
PRESENT = 0b01 UMETA(DisplayName = "Present"),
|
||||
ADDED = 0b11 UMETA(DisplayName = "Added"),
|
||||
REMOVED = 0b10 UMETA(DisplayName = "Removed")
|
||||
};
|
||||
|
||||
#define FIGURE_TOTAL_BLOCKS 64
|
||||
#define FIGURE_BLOCK_SIZE 16
|
||||
|
||||
|
@ -26,6 +17,7 @@ public:
|
|||
// Data Arrays
|
||||
uint8 data[64][16];
|
||||
uint8 decryptedData[64][16];
|
||||
bool dataError;
|
||||
|
||||
// Properties
|
||||
#pragma region manufacturer
|
||||
|
@ -56,7 +48,7 @@ public:
|
|||
// Methods
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
|
||||
uint32 GetFigureID(const FigureDataBlock& DataBlock);
|
||||
uint32 GetFigureID();
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
|
||||
uint32 GetFigureIdByIndex(uint32 index);
|
||||
|
@ -72,3 +64,5 @@ public:
|
|||
uint32 GetUInt(int block, int offset);
|
||||
void Dump(bool decrypted, FString filePath);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
#include "CoreMinimal.h"
|
||||
#include "hidapi.h"
|
||||
#include "SkyPortalDefinitions.h"
|
||||
#include "SkyPortalFigure.h"
|
||||
#include "SkyPortalIO.generated.h"
|
||||
|
||||
|
@ -19,63 +20,6 @@ constexpr auto TIMEOUT = 30000; //milliseconds
|
|||
const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 };
|
||||
const int ProductIds[4] = { 0x150, 0x967, 0x1f17 };
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum EPortalCommand {
|
||||
A UMETA(DisplayName = "Activate"),
|
||||
C UMETA(DisplayName = "Color"),
|
||||
J UMETA(DisplayName = "Advanced color"),
|
||||
L UMETA(DisplayName = "Trap color"),
|
||||
M UMETA(DisplayName = "Music"),
|
||||
Q UMETA(DisplayName = "Query"),
|
||||
R UMETA(DisplayName = "Ready"),
|
||||
S UMETA(DisplayName = "Status")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FPortalStatusData
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Array of statuses
|
||||
UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder))
|
||||
TArray<EFigureStatus> StatusArray;
|
||||
|
||||
// timestamp.
|
||||
// only one byte long. This means that after the value 0xFF, it overflows back to 0x00.
|
||||
// Since these are so far apart, it can be assumed that 0x00 is newer than anything in the range 0xF0 - 0xFF.
|
||||
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
|
||||
uint8 Counter;
|
||||
|
||||
// Should always be true
|
||||
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
|
||||
bool bIsReady;
|
||||
|
||||
explicit FPortalStatusData(uint8 ArraySize = 16, EFigureStatus DefaultStatus = EFigureStatus::NOT_PRESENT) :
|
||||
Counter(0),
|
||||
bIsReady(true)
|
||||
{
|
||||
// Initialisation du tableau StatusArray avec 16 éléments par défaut
|
||||
StatusArray.Init(DefaultStatus, ArraySize);
|
||||
}
|
||||
|
||||
// Overload the == operator
|
||||
// Different only between
|
||||
bool operator==(const FPortalStatusData& Other) const
|
||||
{
|
||||
if (bIsReady == Other.bIsReady && Counter == Other.Counter) {
|
||||
if (StatusArray == Other.StatusArray) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Overload the != operator
|
||||
bool operator!=(const FPortalStatusData& Other) const
|
||||
{
|
||||
return !(*this == Other);
|
||||
}
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
|
||||
|
@ -131,6 +75,8 @@ public:
|
|||
UFUNCTION()
|
||||
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
|
||||
|
||||
FigureData ReadFigureBlocks(uint8 FigureIndex);
|
||||
|
||||
/* Close connection to Portal*/
|
||||
void Close();
|
||||
|
||||
|
|
|
@ -3,27 +3,10 @@
|
|||
#include "Subsystems/EngineSubsystem.h"
|
||||
#include "SkyPortalRunner.h"
|
||||
#include "SkyPortalIO.h"
|
||||
|
||||
|
||||
#include "SkyPortalSubsystem.generated.h"
|
||||
|
||||
#pragma region Definitions
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum EPortalSide {
|
||||
LEFT UMETA(DisplayName = "Left side"),
|
||||
RIGHT UMETA(DisplayName = "Right side"),
|
||||
BOTH UMETA(DisplayName = "Both left and right"),
|
||||
TRAP UMETA(DisplayName = "Trap")
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//// Delegates
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderAddedDelegate, int32, SkylanderID, int32, Index);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderRemovedDelegate, int32, SkylanderID, int32, Index);
|
||||
|
@ -146,22 +129,12 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
|
||||
// deprecated
|
||||
FPortalStatusData OLDParsePortalStatus(const FWriteBlock& ResponseBlock); // deprecated
|
||||
|
||||
EPortalCommand GetPortalCommandFromChar(unsigned char Char); // deprecated
|
||||
|
||||
|
||||
|
||||
/* Sleep the system
|
||||
*
|
||||
* @param sleepMs Sleep time (in milliseconds)
|
||||
*/
|
||||
static void Sleep(int sleepMs);
|
||||
|
||||
bool FalsePositive() const;
|
||||
|
||||
// Pointer to the status checker thread
|
||||
FPortalStatusChecker* StatusChecker;
|
||||
FRunnableThread* StatusCheckerThread;
|
||||
|
|
Loading…
Reference in a new issue