Move tangible state into TangibleComponent

This commit is contained in:
2023-09-25 18:00:34 -04:00
parent 2f5baf2e9f
commit 254524aab6
11 changed files with 211 additions and 72 deletions

View File

@@ -3,11 +3,12 @@
#include "IntegrationGameModeBase.h" #include "IntegrationGameModeBase.h"
#include "lpx-drvutil.hpp" #include "lpx-drvutil.hpp"
#include "DebugPrint.h" #include "DebugPrint.h"
#include "Tangible.h" #include "TangibleComponent.h"
#include "TangibleManager.h" #include "TangibleManager.h"
#include "TangibleInterface.h" #include "TangibleInterface.h"
#include "CommonTypes.h" #include "CommonTypes.h"
#include "AnimQueue.h" #include "AnimQueue.h"
#include "IntegrationGameState.h"
#include <string> #include <string>
#include <string_view> #include <string_view>
@@ -119,11 +120,13 @@ void AIntegrationGameModeBase::MaybeTriggerUpdateTask(float deltaseconds) {
// FStructProperty* sprop = FindFProperty<FStructProperty>(uclass, nname); // FStructProperty* sprop = FindFProperty<FStructProperty>(uclass, nname);
//} //}
#pragma optimize("", off)
void AIntegrationGameModeBase::UpdateTangibles() { void AIntegrationGameModeBase::UpdateTangibles() {
if (!Playing) return; if (!Playing) return;
FlxLockedWrapper w(LockableWrapper); FlxLockedWrapper w(LockableWrapper);
int64 actor = w.GetActor(); int64 actor = w.GetActor();
TangibleManager->SetActor(actor); TangibleManager->SetPlayer(actor);
TangibleManager->SetNear(w.GetNear(actor, 100, 100, 100)); TangibleManager->SetNear(w.GetNear(actor, 100, 100, 100));
for (int64 id : TangibleManager->GetNear()) { for (int64 id : TangibleManager->GetNear()) {
TangibleManager->MakeTangible(id); TangibleManager->MakeTangible(id);
@@ -133,19 +136,16 @@ void AIntegrationGameModeBase::UpdateTangibles() {
StringViewVec aqueues = w.GetAnimationQueues(tanids); StringViewVec aqueues = w.GetAnimationQueues(tanids);
for (int i = 0; i < tanids.Num(); i++) { for (int i = 0; i < tanids.Num(); i++) {
uint64_t tanid = tanids[i]; uint64_t tanid = tanids[i];
std::string_view aqueue = aqueues[i]; UTangibleComponent *t = TangibleManager->GetTangible(tanid);
UlxTangible* t = TangibleManager->GetTangible(tanid); t->AnimTracker.Update(aqueues[i]);
check(t != nullptr);
t->AnimTracker.Update(aqueue);
TArray<uint64> aborted = t->AnimTracker.GetAborted(); TArray<uint64> aborted = t->AnimTracker.GetAborted();
for (uint64 hash : aborted) { for (uint64 hash : aborted) {
IlxTangibleInterface::Execute_AbortAnimation(t->Actor, hash); IlxTangibleInterface::Execute_AbortAnimation(t->GetActor(), hash);
} }
FlxAnimationStep step; FlxAnimationStep step;
ElxAnimationMode mode = t->AnimTracker.GetNextStep(step); ElxAnimationMode mode = t->AnimTracker.GetNextStep(step);
if (mode != ElxAnimationMode::INVALID) { if (mode != ElxAnimationMode::INVALID) {
bool started = IlxTangibleInterface::Execute_StartAnimation(t->Actor, mode, step); bool started = IlxTangibleInterface::Execute_StartAnimation(t->GetActor(), mode, step);
if (started) { if (started) {
t->AnimTracker.StartedStep(step.Hash); t->AnimTracker.StartedStep(step.Hash);
} }
@@ -252,4 +252,16 @@ void AIntegrationGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
ResetToInitialState(); ResetToInitialState();
} }
namespace IntegrationGameState {
UTangibleManager* GetTangibleManager(AActor *actor) {
AGameModeBase* gmb = actor->GetWorld()->GetAuthGameMode();
AIntegrationGameModeBase* igmb = Cast<AIntegrationGameModeBase>(gmb);
if (igmb == nullptr) {
return nullptr;
} else {
return igmb->TangibleManager;
}
}
} // namespace IntegrationGameState

View File

@@ -0,0 +1,7 @@
class UTangibleManager;
namespace IntegrationGameState {
UTangibleManager* GetTangibleManager(AActor *actor);
}

View File

@@ -0,0 +1,34 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SampleActorComponent.h"
// Sets default values for this component's properties
USampleActorComponent::USampleActorComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void USampleActorComponent::BeginPlay()
{
Super::BeginPlay();
// ...
}
// Called every frame
void USampleActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}

View File

@@ -0,0 +1,28 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "SampleActorComponent.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class INTEGRATION_API USampleActorComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
USampleActorComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};

View File

@@ -1,5 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Tangible.h"

View File

@@ -1,31 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "AnimQueue.h"
#include "TangibleInterface.h"
#include "Tangible.generated.h"
/**
*
*/
UCLASS()
class INTEGRATION_API UlxTangible : public UObject
{
GENERATED_BODY()
public:
UPROPERTY()
AActor* Actor;
FlxAnimTracker AnimTracker;
FString Plane;
void Init(AActor* a, const FString &plane) {
Actor = a;
Plane = plane;
}
};

View File

@@ -0,0 +1,16 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "TangibleComponent.h"
#include "TangibleManager.h"
UTangibleComponent::UTangibleComponent()
{
}
void UTangibleComponent::Init(UTangibleManager* tm, AActor* a, int64 id)
{
TangibleManager = tm;
Actor = a;
TangibleId = id;
}

View File

@@ -0,0 +1,56 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AnimQueue.h"
#include "TangibleComponent.generated.h"
/*
* TangibleComponent
*
* The TangibleManager procedurally injects a TangibleComponent
* into the actor. This gives us a place to store tangible-specific
* actor properties, such as the tangible Id, the animation queue,
* and so forth.
*
* To cooperate the with the garbage collector, don't store pointers
* to TangibleComponents in data structures. Instead, store a pointer
* to the actor and then use GetComponentByClass to retrieve the
* TangibleComponent on demand.
*
*/
class UTangibleManager;
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class INTEGRATION_API UTangibleComponent : public UActorComponent
{
GENERATED_BODY()
public:
UTangibleComponent();
// The tangible ID.
UPROPERTY()
uint64 TangibleId;
// The actor that we're a part of.
UPROPERTY()
TWeakObjectPtr<AActor> Actor;
// Our tangible Manager.
UPROPERTY()
TWeakObjectPtr<UTangibleManager> TangibleManager;
// Animation tracker
FlxAnimTracker AnimTracker;
// Current Plane.
FString Plane;
void Init(UTangibleManager* tm, AActor* a, int64 id);
AActor* GetActor() const { return Actor.Get(); }
};

View File

@@ -29,3 +29,5 @@ public:
UFUNCTION(BlueprintImplementableEvent, Category = "Tangible Functionality") UFUNCTION(BlueprintImplementableEvent, Category = "Tangible Functionality")
bool AbortAnimation(int64 hash); bool AbortAnimation(int64 hash);
}; };

View File

@@ -3,6 +3,8 @@
#include "TangibleManager.h" #include "TangibleManager.h"
#include "TangibleInterface.h" #include "TangibleInterface.h"
#include "IntegrationGameState.h"
#include "TangibleComponent.h"
#include "DebugPrint.h" #include "DebugPrint.h"
using namespace DebugPrint; using namespace DebugPrint;
@@ -10,39 +12,51 @@ using namespace DebugPrint;
UTangibleManager::UTangibleManager() { UTangibleManager::UTangibleManager() {
World = nullptr; World = nullptr;
ClassTangibleActor = nullptr; ClassTangibleActor = nullptr;
Actor = 0; Player = 0;
Near = IdView(); Near = IdView();
} }
void UTangibleManager::Init(UWorld *world, UClass* tanact) { void UTangibleManager::Init(UWorld *world, UClass* tanact) {
World = world; World = world;
ClassTangibleActor = tanact; ClassTangibleActor = tanact;
Actor = 0; Player = 0;
Near = IdView(); Near = IdView();
} }
UlxTangible *UTangibleManager::GetTangible(int64 id) { UTangibleComponent *UTangibleManager::GetTangible(int64 id) {
UlxTangible **p = IdToTangible.Find(id); AActor **p = IdToActor.Find(id);
if (p == nullptr) { if (p == nullptr) {
return nullptr; return nullptr;
} else { } else {
return *p; AActor* a = *p;
UTangibleComponent* comp = a->FindComponentByClass<UTangibleComponent>();
check(comp != nullptr);
return comp;
} }
} }
UlxTangible *UTangibleManager::MakeTangible(int64 id) { UTangibleComponent *UTangibleManager::MakeTangible(int64 id) {
UlxTangible *& p = IdToTangible.FindOrAdd(id); AActor *& p = IdToActor.FindOrAdd(id);
if (p == nullptr) { if (p == nullptr) {
FVector location(0,0,0);
FRotator rotation(0, 0, 0);
FActorSpawnParameters params; FActorSpawnParameters params;
AActor* a = World->SpawnActor(ClassTangibleActor, &location, &rotation, params); FVector location(0, 0, 0);
FRotator rotation(0, 0, 0);
UWorld* w = GetWorld();
AActor* a = w->SpawnActor(ClassTangibleActor, &location, &rotation, params);
check(a != nullptr); check(a != nullptr);
check(a->GetClass()->ImplementsInterface(UlxTangibleInterface::StaticClass())); check(a->GetClass()->ImplementsInterface(UlxTangibleInterface::StaticClass()));
p = NewObject<UlxTangible>(); // Insert a TangibleComponent into the actor.
p->Init(a, TEXT("")); UActorComponent* ac = a->AddComponentByClass(UTangibleComponent::StaticClass(), false, FTransform::Identity, false);
UTangibleComponent* tc = Cast<UTangibleComponent>(ac);
check(tc != nullptr);
tc->Init(this, a, id);
p = a;
return tc;
} else {
UTangibleComponent* comp = p->FindComponentByClass<UTangibleComponent>();
check(comp != nullptr);
return comp;
} }
return p;
} }
void UTangibleManager::DeleteTangible(int64 id) { void UTangibleManager::DeleteTangible(int64 id) {
@@ -51,10 +65,10 @@ void UTangibleManager::DeleteTangible(int64 id) {
UTangibleManager::IdArray UTangibleManager::GetLive() { UTangibleManager::IdArray UTangibleManager::GetLive() {
IdArray result; IdArray result;
result.SetNum(IdToTangible.Num()); result.SetNum(IdToActor.Num());
int next = 0; int next = 0;
for (auto &pair : IdToTangible) { for (auto &pair : IdToActor) {
result[next++] = pair.Key; result[next++] = pair.Key;
} }
return result; return result;
} }

View File

@@ -5,7 +5,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "UObject/NoExportTypes.h" #include "UObject/NoExportTypes.h"
#include "CommonTypes.h" #include "CommonTypes.h"
#include "Tangible.h" #include "TangibleComponent.h"
#include "TangibleManager.generated.h" #include "TangibleManager.generated.h"
UCLASS() UCLASS()
@@ -18,19 +18,21 @@ public:
using IdArray = CommonTypes::IdArray; using IdArray = CommonTypes::IdArray;
using IdView = CommonTypes::IdView; using IdView = CommonTypes::IdView;
// A pointer to the UWorld. // A pointer to our world.
UWorld* World; UPROPERTY()
TWeakObjectPtr<UWorld> World;
// A pointer to uclass TangibleActor. // A pointer to uclass TangibleActor. This is the class
// of actors that we create (for now).
UPROPERTY() UPROPERTY()
TSubclassOf<AActor> ClassTangibleActor; TSubclassOf<AActor> ClassTangibleActor;
// Given a tangible ID, look up actor pointer (or NULL if actor was deleted) // Given a tangible ID, look up actor pointer (or NULL if actor was deleted)
UPROPERTY() UPROPERTY()
TMap<int64, UlxTangible*> IdToTangible; TMap<int64, AActor*> IdToActor;
// Actor tangible Id. // Player's tangible Id.
int64 Actor; int64 Player;
// Tangibles near the actor. // Tangibles near the actor.
IdView Near; IdView Near;
@@ -42,19 +44,23 @@ public:
// //
void Init(UWorld *world, UClass* tanact); void Init(UWorld *world, UClass* tanact);
// Get a pointer to our world.
//
UWorld* GetWorld() const override { return World.Get(); }
// Get the tangible if it exists, otherwise return NULL // Get the tangible if it exists, otherwise return NULL
UlxTangible* GetTangible(int64 id); UTangibleComponent* GetTangible(int64 id);
// Get the tangible if it exists, otherwise create it. // Get the tangible if it exists, otherwise create it.
UlxTangible* MakeTangible(int64 id); UTangibleComponent* MakeTangible(int64 id);
// Delete the tangible. // Delete the tangible.
void DeleteTangible(int64 id); void DeleteTangible(int64 id);
// Get/Set the Id of the actor. // Get/Set the Id of the actor.
// //
int64 GetActor() const { return Actor; }; int64 GetPlayer() const { return Player; };
void SetActor(int64 id) { Actor = id; } void SetPlayer(int64 id) { Player = id; }
// Get/Set the list of tangibles near the player, according to Luprex. // Get/Set the list of tangibles near the player, according to Luprex.
// //