– https://pastebin.com/9zY64PrR
/////////////////////////////CustumPlayerController.h////////////////////////////////////////////
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/PlayerController.h"
#include "MyInput.h"
#include "CustumPlayerController.generated.h"
/**
*
*/
UCLASS(config=Game)
class OCULUSTEST_API ACustumPlayerController: public APlayerController, public FRunnable
{
GENERATED_BODY()
private:
//The boolean that controlls the lifetime of our thread. While being true the thread will run.
bool Playing;
/* Thread begin */
/** Singleton instance, can access the thread any time via static accessor, if it is active! */
static ACustumPlayerController* Runnable;
/** Thread to run the worker FRunnable on */
FRunnableThread* Thread;
//Done?
bool IsFinished() const
{
return !Playing;
}
// Begin FRunnable interface.
virtual uint32 Run();
virtual void Stop();
// End FRunnable interface
/** Makes sure this thread has stopped properly */
void EnsureCompletion();
/** Shuts down the thread. Static so it can easily be called from outside the thread context */
void Shutdown();
/* Thread end */
///////////////////////////////////////////////////////////
Omitted variables
and functions
///////////////////////////////////////////////////////////
//Constructors and destructors.
ACustumPlayerController(const class FObjectInitializer& PCIP);
~ACustumPlayerController();
public:
//Get the singleton thread.
static ACustumPlayerController* GetThread();
//Set from the editor for easy testing.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timing")
float PositionUpdateTimer;
//This function will be called from BP and used to teleport the character. Called every tick.
UFUNCTION(BlueprintCallable, Category = "Timing")
FVector GetNewLocation(float DeltaTime);
//This function will be called via BP on the event BeginPLay
UFUNCTION(BlueprintCallable, Category = "Timing")
void Init();
};
////////////////////////CustumPlayerController.cpp//////////////////////////////////
// Fill out your copyright notice in the Description page of Project Settings.
#include "Other headers"
#include "CustumPlayerController.h"
//***********************************************************
//Thread Worker Starts as NULL, prior to being instanced
// This line is essential! Compiler error without it
ACustumPlayerController* ACustumPlayerController::Runnable = NULL;
//***********************************************************
//Sets up the PlayerController
ACustumPlayerController::ACustumPlayerController(const class FObjectInitializer& PCIP) : Super(PCIP)
{
PrimaryActorTick.bCanEverTick = true;
float PositionUpdateTimer = 0.25f;
Playing = false;
/////////////////////////////////////////////////////////////////////
Initialize variables
////////////////////////////////////////////////////////////////////
const bool bAutoDeleteSelf = false;
const bool bAutoDeleteRunnable = false;
Thread = FRunnableThread::Create(this, TEXT("ACustumPlayerController"), bAutoDeleteSelf, bAutoDeleteRunnable, 0, TPri_BelowNormal); //windows default = 8mb for thread, could specify more
};
ACustumPlayerController::~ACustumPlayerController()
{
Thread->Kill();
delete Thread;
Thread = NULL;
};
//Run
uint32 ACustumPlayerController::Run()
{
//Initial wait before starting
FPlatformProcess::Sleep(0.03);
//While not told to stop this thread
// and not yet finished finding Prime Numbers
while(!IsFinished()) {
//Run the heavy calculations in a different thread.
UpdateData();
//prevent thread from using too many resources
FPlatformProcess::Sleep(0.01);
}
return 0;
}
//stop
void ACustumPlayerController::Stop()
{
Thread->Kill();
}
void ACustumPlayerController::Shutdown()
{
if(Runnable) {
Runnable->Exit();
Runnable->FinishDestroy();
Runnable = NULL;
}
}
ACustumPlayerController* ACustumPlayerController::GetThread()
{
if(!Runnable && FPlatformProcess::SupportsMultithreading()) {
Runnable = new ACustumPlayerController(FObjectInitializer::FObjectInitializer());
}
return Runnable;
}
//Prime the controller.
void ACustumPlayerController::Init()
{
if(!Runnable && FPlatformProcess::SupportsMultithreading()) {
Runnable = new ACustumPlayerController(FObjectInitializer::FObjectInitializer());
}
//Set the rest of the variables and states.
}
////////////////////Code to be run in the thread/////////////////////////////////
void ACustumPlayerController::Update()
{
//Limit the number of updates.
if (CurrDeltaSec < PositionUpdateTimer) return;
CurrDeltaSec -= PositionUpdateTimer;
///////////////////////////////////////////////////////////////
Heavy calculations and slow input device interaction
///////////////////////////////////////////////////////////////
}
///////////////////////////////End of code to be run in the thread/////////////////////////////////
//Return the new position. This function is called every tick.
FVector ACustumPlayerController::GetNewLocation(float DeltaTime)
{
CurrDeltaSec += DeltaTime;
return LatestPosition;
}
传统写法
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
/**
*
*/
class UDataSingleTon
{
public:
UDataSingleTon();
~UDataSingleTon();
float TestValue = 1.0f;
static UDataSingleTon* GetInstance();
static void DeleteSingleTon();
private:
static UDataSingleTon* _instance;
};
““
// Fill out your copyright notice in the Description page of Project Settings.
include “UDataSingleTon.h”
UDataSingleTon* UDataSingleTon::_instance=NULL;
UDataSingleTon* UDataSingleTon::GetInstance()
{
if (_instance==NULL)
{
_instance = new UDataSingleTon();
}
return _instance;
}
void UDataSingleTon::DeleteSingleTon()
{
_instance = nullptr;
delete _instance;
}
UDataSingleTon::UDataSingleTon()
{
UE_LOG(LogTemp, Warning, TEXT(“构造”));
}
UDataSingleTon::~UDataSingleTon()
{
UE_LOG(LogTemp, Warning, TEXT(“释放”));
}
““