I am trying to create a runnable object to run code in a background thread. It’s used to generate a level and it compiles as long as I don’t include it somewhere. I’ve tried including it in a couple different classes and it fails.
.h
#pragma once
#include "CoreMinimal.h"
class ULevelGeneratorParams;
class ULevelData;
/**
* Performs the actions of generating a level in a background thread.
*/
class MINESEEKER_API GenerateLevelRunnable : public FRunnable // as soon as I include this class in another class, FRunnable becomes an unknown type
{
public:
static GenerateLevelRunnable Start(ULevelGeneratorParams *parameters);
GenerateLevelRunnable();
~GenerateLevelRunnable();
virtual bool Init();
virtual uint32 Run();
virtual void Stop();
private:
static const int32 MINES_EASY = 10;
static const int32 MINES_MEDIUM = 50;
static const int32 MINES_HARD = 100;
static const int32 WIDTH_HEIGHT_EASY = 10;
static const int32 WIDTH_HEIGHT_MEDIUM = 20;
static const int32 WIDTH_HEIGHT_HARD = 30;
static ULevelGeneratorParams *Parameters;
// Generates a unique vector and places it into the provided array.
void GenerateUniqueVector(TArray<FVector2D> *locations, ULevelData *data);
};
c++
#include "GenerateLevelRunnable.h"
#include "Runnable.h"
#include "LevelGeneratorParams.h"
#include "LevelData.h"
GenerateLevelRunnable GenerateLevelRunnable::Start(ULevelGeneratorParams *parameters)
{
GenerateLevelRunnable::Parameters = parameters;
return new GenerateLevelRunnable();
}
GenerateLevelRunnable::GenerateLevelRunnable()
{
}
GenerateLevelRunnable::~GenerateLevelRunnable()
{
delete GenerateLevelRunnable::Parameters;
GenerateLevelRunnable::Parameters = NULL;
}
bool GenerateLevelRunnable::Init()
{
return true;
}
uint32 GenerateLevelRunnable::Run()
{
ULevelData *data = NewObject<ULevelData>();
TArray<FVector2D> mineLocations;
EDifficulty difficulty = GenerateLevelRunnable::Parameters->GetDifficulty();
switch (difficulty)
{
case EDifficulty::EASY:
data->SetWidth(WIDTH_HEIGHT_EASY);
data->SetHeight(WIDTH_HEIGHT_EASY);
for (int8 i = 0; i < MINES_EASY; i++)
{
GenerateUniqueVector(&mineLocations, data);
}
break;
case EDifficulty::MEDIUM:
data->SetWidth(WIDTH_HEIGHT_MEDIUM);
data->SetHeight(WIDTH_HEIGHT_MEDIUM);
for (int8 i = 0; i < MINES_MEDIUM; i++)
{
GenerateUniqueVector(&mineLocations, data);
}
break;
case EDifficulty::HARD:
data->SetWidth(WIDTH_HEIGHT_HARD);
data->SetHeight(WIDTH_HEIGHT_HARD);
for (int8 i = 0; i < MINES_HARD; i++)
{
GenerateUniqueVector(&mineLocations, data);
}
break;
default:
checkf(false, TEXT("Value for difficulty is not valid"));
break;
}
data->SetMineLocations(mineLocations);
return uint32();
}
void GenerateLevelRunnable::Stop()
{
}
void GenerateLevelRunnable::GenerateUniqueVector(TArray<FVector2D>* locations, ULevelData * data)
{
FVector2D location;
location.X = FMath::RandRange(1, data->GetWidth());
location.Y = FMath::RandRange(1, data->GetWidth());
if (locations->Contains(location))
{
GenerateUniqueVector(locations, data);
}
else
{
locations->Add(location);
}
}
I have tried different combinations of commenting out includes and trying it ins different classes and the compiler fails as soon as I import this into another class and I can’t seem to figure out why. Any ideas what is causing this to fail?
Here is the error I am getting
CompilerResultsLog: Error: GeneratBlueprintFunctionLibrary.cpp.obj : error LNK2019: unresolved external symbol "public: virtual __cdecl GenerateLevelRunnable::~GenerateLevelRunnable(void)" (??1GenerateLevelRunnable@@UEAA@XZ) referenced in function "public: virtual void * __cdecl
GenerateLevelRunnable::`vector deleting destructor'(unsigned int)" (??_EGenerate
LevelRunnable@@UEAAPEAXI@Z)
CompilerResultsLog: Error: GeneratBlueprintFunctionLibrary.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl GenerateLevelRunnable::Init(void)" (?Init@GenerateLevelRunnable@@UEAA_NXZ)
CompilerResultsLog: Error: GeneratBlueprintFunctionLibrary.cpp.obj : error LNK2001: unresolved external symbol "public: virtual unsigned int __cdecl GenerateLevelRunnable::Run(void)" (?Run@GenerateLevelRunnable@@UEAAIXZ)
CompilerResultsLog: Error: GeneratBlueprintFunctionLibrary.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl GenerateLevelRunnable::Stop(void)" (?Stop@GenerateLevelRunnable@@UEAAXXZ)
CompilerResultsLog: Error: C:\dev\projects\ue4\MineSeeker\Binaries\Win64\UE4Editor-MineSeeker-2451.dll : fatal error LNK1120: 4 unresolved externals
CompilerResultsLog: ERROR: UBT ERROR: Failed to produce item: C:\dev\projects\ue4\MineSeeker\Binaries\Win64\UE4Editor-MineSeeker-2451.dll