-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathXmsRepresentationProcessor.cpp
More file actions
100 lines (80 loc) · 3.67 KB
/
Copy pathXmsRepresentationProcessor.cpp
File metadata and controls
100 lines (80 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) 2025 Xist.GG
#include "Representation/XmsRepresentationProcessor.h"
#include "MassExecutionContext.h"
#include "XmsRepSubsystem.h"
#include "Attributes/Lifespan/XmsLifespan.h"
#include "EntityRegistry/XmsEntityMetaData.h"
#include "Common/XmsFragments.h"
//----------------------------------------------------------------------//
// UXimVizEntityAdded
//----------------------------------------------------------------------//
UXmsRepresentationProcessor::UXmsRepresentationProcessor()
: Query(*this)
{
ProcessingPhase = EMassProcessingPhase::PostPhysics;
ExecutionFlags = static_cast<int32>(EProcessorExecutionFlags::All);
ExecutionOrder.ExecuteInGroup = FName("Representation");
}
void UXmsRepresentationProcessor::ConfigureQueries(const TSharedRef<FMassEntityManager>& EntityManager)
{
Query.AddTagRequirement<FXmsT_Represent>(EMassFragmentPresence::All);
Query.AddConstSharedRequirement<FXmsCSF_MetaData>(EMassFragmentPresence::All);
Query.AddRequirement<FXmsF_Transform>(EMassFragmentAccess::ReadOnly);
Query.AddRequirement<FXmsF_Lifespan>(EMassFragmentAccess::ReadOnly, EMassFragmentPresence::Optional);
ProcessorRequirements.AddSubsystemRequirement<UXmsRepSubsystem>(EMassFragmentAccess::ReadWrite);
}
void UXmsRepresentationProcessor::Execute(FMassEntityManager& EntityManager, FMassExecutionContext& Context)
{
QUICK_SCOPE_CYCLE_COUNTER(UXmsRepresentationProcessor);
std::atomic<int32> TotalNumEntities = 0;
TQueue<TArray<const FXmsEntityRepresentationData>> DataQueue;
Query.ParallelForEachEntityChunk(Context, [&TotalNumEntities, &DataQueue](FMassExecutionContext& Context)
{
// MetaData is shared by all Entities in this chunk
const auto& MetaData = Context.GetConstSharedFragment<FXmsCSF_MetaData>();
// Every Entity has its own Transform
const auto Transforms = Context.GetFragmentView<FXmsF_Transform>();
// Some Entities have Lifespan, but it's optional.
const auto Lifespans = Context.GetFragmentView<FXmsF_Lifespan>();
const bool bHaveLifespan = Lifespans.Num() > 0; // Do the Entities in this chunk have Lifespans?
// Allocate memory to store data for the Game/Render threads
TArray<const FXmsEntityRepresentationData> Entities;
Entities.Reserve(Context.GetNumEntities());
// Iterate over each Entity in this chunk, copy relevant info
for (FMassExecutionContext::FEntityIterator EntityIt = Context.CreateEntityIterator(); EntityIt; ++EntityIt)
{
const FXmsF_Transform& Transform = Transforms[*EntityIt];
// Any Entity without a Lifespan will report AlphaAge = -1
// If this chunk has a lifespan, AlphaAge will be computed based on the Lifespan data.
float AlphaAge {-1.};
if (bHaveLifespan)
{
const FXmsF_Lifespan& Lifespan = Lifespans[*EntityIt];
AlphaAge = Lifespan.MaxAge >= KINDA_SMALL_NUMBER && not Lifespan.IsImmortal()
? Lifespan.CurrentAge / Lifespan.MaxAge
: 1.; // either Immortal or at max expected age
}
// This is the data that will be made available to the Game/Render systems
const FXmsEntityRepresentationData Data {
.Entity = Context.GetEntity(*EntityIt),
.MetaType = MetaData.MetaType,
.Location = Transform.Location,
.AlphaAge = AlphaAge,
};
Entities.Emplace(Data);
}
// Thread-safe queue and TotalNumEntities count
DataQueue.Enqueue(Entities);
TotalNumEntities += Context.GetNumEntities();
});
// Update UXmsRepSubsystem data
UXmsRepSubsystem& RepSubsystem = Context.GetMutableSubsystemChecked<UXmsRepSubsystem>();
TArray<const FXmsEntityRepresentationData> Data;
// Thread-safe rejoining of queue data
RepSubsystem.MassPrepare(TotalNumEntities);
while (DataQueue.Dequeue(OUT Data))
{
RepSubsystem.MassAppend(Data);
}
RepSubsystem.MassCommit();
}