CelticCraft/Plugins/VoxelFree/Source/VoxelGraph/Private/VoxelNode.cpp

191 lines
No EOL
4.1 KiB
C++

// Copyright 2020 Phyronnaz
#include "VoxelNode.h"
#include "IVoxelGraphEditor.h"
#include "VoxelGraphGenerator.h"
#include "VoxelGraphErrorReporter.h"
#include "EdGraph/EdGraphNode.h"
#if WITH_EDITOR
void UVoxelGraphNodeInterface::PostLoad()
{
Super::PostLoad();
ErrorMsg.Empty();
}
void UVoxelGraphNodeInterface::ReconstructNode()
{
Super::ReconstructNode();
InfoMsg.Empty();
WarningMsg.Empty();
ErrorMsg.Empty();
}
#endif
int32 UVoxelNode::GetInputPinIndex(const FGuid& PinId)
{
for (int32 I = 0; I < InputPins.Num(); I++)
{
if (InputPins[I].PinId == PinId)
{
return I;
}
}
return -1;
}
int32 UVoxelNode::GetOutputPinIndex(const FGuid& PinId)
{
for (int32 I = 0; I < OutputPins.Num(); I++)
{
if (OutputPins[I].PinId == PinId)
{
return I;
}
}
return -1;
}
bool UVoxelNode::HasInputPinWithCategory(EVoxelPinCategory Category) const
{
for (int32 i = 0; i < GetMinInputPins(); i++)
{
if (GetInputPinCategory(i) == Category)
{
return true;
}
}
return false;
}
bool UVoxelNode::HasOutputPinWithCategory(EVoxelPinCategory Category) const
{
for (int32 i = 0; i < GetOutputPinsCount(); i++)
{
if (GetOutputPinCategory(i) == Category)
{
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FText UVoxelNode::GetTitle() const
{
#if WITH_EDITOR
return GetClass()->GetDisplayNameText();
#else
return FText::GetEmpty();
#endif
}
FText UVoxelNode::GetTooltip() const
{
#if WITH_EDITOR
return GetClass()->GetToolTipText();
#else
return FText::GetEmpty();
#endif
}
void UVoxelNode::LogErrors(FVoxelGraphErrorReporter& ErrorReporter)
{
if (IsOutdated())
{
ErrorReporter.AddMessageToNode(this, "outdated node, please right click and press Reconstruct Node", EVoxelGraphNodeMessageType::Error);
}
#if WITH_EDITOR
for (TFieldIterator<FProperty> It(GetClass()); It; ++It)
{
auto* Property = *It;
if (Property->HasMetaData(STATIC_FNAME("NonNull")))
{
auto* ObjectProperty = CastField<FObjectProperty>(Property);
if (ensure(ObjectProperty))
{
if (!*ObjectProperty->ContainerPtrToValuePtr<UObject*>(this))
{
ErrorReporter.AddMessageToNode(this, FString::Printf(TEXT("%s is null"), *Property->GetDisplayNameText().ToString()), EVoxelGraphNodeMessageType::Error);
}
}
}
}
#endif
}
#if WITH_EDITOR
void UVoxelNode::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
{
Super::PostEditChangeChainProperty(PropertyChangedEvent);
if (Graph && GraphNode && PropertyChangedEvent.Property && PropertyChangedEvent.ChangeType != EPropertyChangeType::Interactive)
{
bool bReconstructNode = false;
for (auto* Property : PropertyChangedEvent.PropertyChain)
{
if (Property && Property->HasMetaData(STATIC_FNAME("ReconstructNode")))
{
bReconstructNode = true;
break;
}
}
UpdatePreview(bReconstructNode);
}
MarkPackageDirty();
}
void UVoxelNode::PostLoad()
{
Super::PostLoad();
// Make sure voxel nodes are transactional (so they work with undo system)
SetFlags(RF_Transactional);
InputPinCount = FMath::Clamp(InputPinCount, GetMinInputPins(), GetMaxInputPins());
if (IsOutdated())
{
FVoxelGraphErrorReporter::AddMessageToNodeInternal(this, "outdated node, please right click and press Reconstruct Node", EVoxelGraphNodeMessageType::Error);
}
}
#endif
void UVoxelNode::UpdatePreview(bool bReconstructNode) const
{
#if WITH_EDITOR
if (bReconstructNode)
{
// Reconstruct before updating preview to have the right output count
GraphNode->ReconstructNode();
Graph->CompileVoxelNodesFromGraphNodes();
}
IVoxelGraphEditor::GetVoxelGraphEditor()->UpdatePreview(Graph, EVoxelGraphPreviewFlags::UpdateTextures);
#endif
}
bool UVoxelNode::IsOutdated() const
{
if (InputPins.Num() < GetMinInputPins() ||
InputPins.Num() > GetMaxInputPins() ||
InputPins.Num() != InputPinCount ||
OutputPins.Num() != GetOutputPinsCount())
{
return true;
}
#if WITH_EDITORONLY_DATA
if (GraphNode && GraphNode->IsOutdated())
{
return true;
}
#endif
return false;
}