๐งฌ Diagnosis System
Overview
NOTE: This system uses advanced C++ principles. It assumes you're familiar with:
- Smart Pointers (
TUniquePtrand move semantics)- Const References (ensuring safe and immutable data access)
This system powers the disease and shock simulation in the Virtual Anatomy project. It defines diagnosis metadata (e.g., symptoms, parameters, FX, logic) that gets used in simulation runtime.
Currently supported diagnoses include: - HyperVolumetric Shock - Cardiogenic Shock - Obstructive Shock - Distributive Shock - Death (as a diagnosis)
It is designed to be extensible, so more diagnoses can be added with minimal effort.
๐ง Core Design Principles
- All diagnoses are created and owned by
UDiagnosisRegistery. - They are stored as
TUniquePtr<UCPP_Diagnosis>โ enforcing single ownership. - Only const references are returned to external systems (e.g. SimulationManager).
- Construction of each diagnosis is handled via a
DiagnosisBuilder, using fluent method chaining.
โ ๏ธ Never manually copy a
UCPP_Diagnosisor break ownership with raw pointers.
๐ฆ Components
UDiagnosisRegistery
- Owns all
UCPP_Diagnosisinstances. - Provides public
GetDiagnosisByType()access. - Initializes all diagnoses in
BuildDiagnosisList().
UCPP_Diagnosis
- Encapsulates all diagnosis-related data:
- Simulation parameters (
FSimulationSlideBarsParameters) - Title + description
- Enum type (
EDiagnosisType) - FX (
TArray<FDiagnosisEffect>) - UI Indicators (
TArray<UShockIndicator*>) - Runtime logic class (
UShockBehavior*)
DiagnosisBuilder
- Used to create each diagnosis instance with a fluent interface.
- Enforces construction rules and prevents misuse.
๐งพ Diagnosis Type Enum
The simulation system uses the EDiagnosisType enum to identify each diagnosis uniquely.
UENUM(BlueprintType)
enum class EDiagnosisType : uint8
{
Healthy = 0,
HyperVolumetricShock,
CardiogenicShock,
ObstructiveShock,
DistributiveShock,
Death
};
This enum is used in dropdown selection, simulation flow, and builder logic.
๐ How to Add a New Diagnosis
1. Extend the Enum
In Types/DiagnosisTypes.h:
enum class EDiagnosisType : uint8
{
Healthy = 0,
HyperVolumetricShock,
// ...
AnaphylacticShock // new
};
2. Add to UI Dropdown
In UCPP_DiagnosisDropDownMenu::NativePreConstruct():
DiseaseOptions.Add("Anaphylactic Shock", EDiagnosisType::AnaphylacticShock);
3. Build It in the Registery
In UDiagnosisRegistery::BuildDiagnosisList():
FSimulationSlideBarsParameters anaParams;
anaParams.Speed = 0.7f;
anaParams.BloodThickness = 200;
anaParams.BeatsPerMinute = 180;
auto newDiagnosis =
DiagnosisBuilder(this)
.SetName("Anaphylactic Shock")
.SetDescription("Severe allergic reaction leading to shock")
.SetDiagnosisType(EDiagnosisType::AnaphylacticShock)
.SetSimulationParameters(anaParams)
.AddIndicator("Neck", "Swelling", "Severe neck swelling", nullptr)
.AddEffect(AllergyFX, true, "Head")
.SetBehavior(NewObject<UAnaphylacticShockBehavior>(this))
.Build();
DiagnosisList.Add(MoveTemp(newDiagnosis));
๐ Runtime Flow
Diagnosis Switching
When the user selects a diagnosis:
UCPP_SimulationManager::ChangeDiagnosis()is called.- Active FX and widgets are cleared.
- New diagnosis is fetched from
UDiagnosisRegistery. - All relevant indicators, FX, temp displays are spawned.
- The
UShockBehavior(if present) hasOnEnter()called. - Changes are propagated via
FChangeDiagnosisdelegate.
Example Listener
void ACPP_BloodPathSystem::HandleDiagnosisChange(UCPP_Diagnosis& selectedDiagnosis)
{
HandleSimulationUpdate(selectedDiagnosis.GetSimulationParameters());
BloodParticleComponent->ReinitializeSystem();
}
๐ฌ Optional Extensions per Diagnosis
| Feature | Class |
|---|---|
| UI Dots | UShockIndicator |
| Niagara FX | FDiagnosisEffect |
| Runtime Logic | UShockBehavior subclass |
| 3D Temp Displays | AFloatingTemperatureLabel |
These components are optional. The builder allows you to skip any of them.
๐ Class Summary
| Class | Role |
|---|---|
UCPP_Diagnosis |
Holds one diagnosis's data |
UDiagnosisRegistery |
Owns all diagnoses |
DiagnosisBuilder |
Fluent builder for diagnosis setup |
UShockIndicator |
UI breathing dot anchor/socket |
FDiagnosisEffect |
Niagara FX setup per diagnosis |
UShockBehavior |
Runtime logic (tickable) |
AFloatingTemperatureLabel |
Floating 3D widget with temp values |
๐ง Developer Reminders
- โ
Always use
DiagnosisBuilderto create a diagnosis. - โ
Use
MoveTemp()when adding to the list. - โ
Runtime logic should go into your
UShockBehaviorsubclass. - โ ๏ธ Never copy or leak
UCPP_Diagnosispointers. - โ ๏ธ Socket names must match skeleton socket bones.