More progress on MCP
This commit is contained in:
@@ -330,3 +330,4 @@ MCPFetcher& MCPFetcher::ToGraph()
|
||||
|
||||
return TypeMismatch(TEXT("ToGraph"), TEXT("Graph or Material"));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "MCPNotifier.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "MaterialEditingLibrary.h"
|
||||
|
||||
void MCPNotifier::PreEditAddObject(UObject* Obj)
|
||||
{
|
||||
if (!Obj) return;
|
||||
bool bAlreadyInSet = false;
|
||||
TouchedSet.Add(Obj, &bAlreadyInSet);
|
||||
if (bAlreadyInSet) return;
|
||||
TouchedArray.Add(Obj);
|
||||
if (bInsidePrePost)
|
||||
Obj->PreEditChange(nullptr);
|
||||
}
|
||||
|
||||
void MCPNotifier::PreEdit()
|
||||
{
|
||||
bInsidePrePost = true;
|
||||
for (UObject* Obj : TouchedArray)
|
||||
Obj->PreEditChange(nullptr);
|
||||
}
|
||||
|
||||
void MCPNotifier::PostEdit()
|
||||
{
|
||||
TSet<UEdGraphNode*> Nodes;
|
||||
TSet<UEdGraph*> Graphs;
|
||||
TSet<UMaterial*> Materials;
|
||||
TSet<UBlueprint*> Blueprints;
|
||||
for (int32 i = TouchedArray.Num() - 1; i >= 0; --i)
|
||||
{
|
||||
UObject* Obj = TouchedArray[i];
|
||||
Obj->PostEditChange();
|
||||
Obj->MarkPackageDirty();
|
||||
|
||||
if (UEdGraphNode* Node = ::Cast<UEdGraphNode>(Obj))
|
||||
Nodes.Add(Node);
|
||||
|
||||
if (UEdGraph* Graph = ::Cast<UEdGraph>(Obj))
|
||||
Graphs.Add(Graph);
|
||||
|
||||
if (UBlueprint* BP = ::Cast<UBlueprint>(Obj))
|
||||
Blueprints.Add(BP);
|
||||
|
||||
if (UMaterialInterface* MatIface = ::Cast<UMaterialInterface>(Obj))
|
||||
if (UMaterial* BaseMat = MatIface->GetMaterial())
|
||||
Materials.Add(BaseMat);
|
||||
}
|
||||
for (UEdGraphNode* Node : Nodes)
|
||||
Node->ReconstructNode();
|
||||
for (UEdGraph* Graph : Graphs)
|
||||
Graph->NotifyGraphChanged();
|
||||
for (UMaterial *Material : Materials)
|
||||
UMaterialEditingLibrary::RebuildMaterialInstanceEditors(Material);
|
||||
for (UBlueprint *Blueprint : Blueprints)
|
||||
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(Blueprint);
|
||||
|
||||
if (GEditor)
|
||||
GEditor->RedrawAllViewports();
|
||||
|
||||
bInsidePrePost = false;
|
||||
}
|
||||
@@ -1,18 +1,22 @@
|
||||
#include "MCPProperty.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Materials/MaterialExpression.h"
|
||||
#include "MaterialGraph/MaterialGraphNode.h"
|
||||
|
||||
MCPProperty::MCPProperty(FProperty* InProp, void* Container)
|
||||
: Prop(InProp), ValuePtr(InProp ? InProp->ContainerPtrToValuePtr<void>(Container) : nullptr) {}
|
||||
MCPProperty::MCPProperty(FProperty* InProp, void* InContainer)
|
||||
: Prop(InProp), Container(InContainer) {}
|
||||
|
||||
FString MCPProperty::GetText() const
|
||||
{
|
||||
FString Result;
|
||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
||||
Prop->ExportTextItem_Direct(Result, ValuePtr, nullptr, nullptr, PPF_None);
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool MCPProperty::SetText(const FString& Value, MCPErrorCallback Error)
|
||||
{
|
||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
||||
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, nullptr, PPF_None);
|
||||
if (!ImportResult)
|
||||
{
|
||||
@@ -20,5 +24,78 @@ bool MCPProperty::SetText(const FString& Value, MCPErrorCallback Error)
|
||||
*Value, *MCPUtils::FormatName(Prop), *Prop->GetCPPType()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Prop->GetOwnerClass()->IsChildOf(UMaterialExpression::StaticClass()))
|
||||
{
|
||||
UMaterialExpression* Expr = static_cast<UMaterialExpression*>(Container);
|
||||
Expr->ForcePropertyValueChanged(Prop);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TArray<MCPProperty> MCPProperty::GetAll(UObject* Obj, EPropertyFlags Flags)
|
||||
{
|
||||
TArray<MCPProperty> Result;
|
||||
if (!Obj) return Result;
|
||||
for (TFieldIterator<FProperty> It(Obj->GetClass()); It; ++It)
|
||||
{
|
||||
if (Flags != 0 && !It->HasAnyPropertyFlags(Flags)) continue;
|
||||
Result.Emplace(*It, Obj);
|
||||
}
|
||||
if (UMaterialGraphNode* MatNode = Cast<UMaterialGraphNode>(Obj))
|
||||
{
|
||||
if (UMaterialExpression* Expr = MatNode->MaterialExpression)
|
||||
{
|
||||
for (TFieldIterator<FProperty> It(Expr->GetClass()); It; ++It)
|
||||
{
|
||||
if (Flags != 0 && !It->HasAnyPropertyFlags(Flags)) continue;
|
||||
Result.Emplace(*It, Expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<MCPProperty> MCPProperty::GetAllSubstring(UObject* Obj, EPropertyFlags Flags, const FString& Substring)
|
||||
{
|
||||
TArray<MCPProperty> All = GetAll(Obj, Flags);
|
||||
if (Substring.IsEmpty()) return All;
|
||||
TArray<MCPProperty> Result;
|
||||
for (const MCPProperty& P : All)
|
||||
{
|
||||
if (MCPUtils::FormatName(P.Prop).Contains(Substring, ESearchCase::IgnoreCase))
|
||||
Result.Add(P);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<MCPProperty> MCPProperty::GetAllExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name)
|
||||
{
|
||||
TArray<MCPProperty> All = GetAll(Obj, Flags);
|
||||
TArray<MCPProperty> Result;
|
||||
for (const MCPProperty& P : All)
|
||||
{
|
||||
if (MCPUtils::Identifies(Name, P.Prop))
|
||||
Result.Add(P);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
MCPProperty MCPProperty::GetOneExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name, MCPErrorCallback Error)
|
||||
{
|
||||
TArray<MCPProperty> Matches = GetAllExactMatch(Obj, Flags, Name);
|
||||
if (Matches.Num() == 0)
|
||||
{
|
||||
Error.SetError(FString::Printf(TEXT("Property '%s' not found on %s"),
|
||||
*Name, *MCPUtils::FormatName(Obj->GetClass())));
|
||||
return MCPProperty();
|
||||
}
|
||||
if (Matches.Num() > 1)
|
||||
{
|
||||
Error.SetError(FString::Printf(TEXT("Ambiguous property '%s' on %s"),
|
||||
*Name, *MCPUtils::FormatName(Obj->GetClass())));
|
||||
return MCPProperty();
|
||||
}
|
||||
return Matches[0];
|
||||
}
|
||||
|
||||
@@ -810,6 +810,7 @@ void MCPUtils::PreEdit(const TArray<UObject*>& Objects)
|
||||
|
||||
void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
|
||||
{
|
||||
TSet<UEdGraphNode*> Nodes;
|
||||
TSet<UEdGraph*> Graphs;
|
||||
TSet<UMaterial*> Materials;
|
||||
TSet<UBlueprint*> Blueprints;
|
||||
@@ -819,6 +820,9 @@ void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
|
||||
Obj->PostEditChange();
|
||||
Obj->MarkPackageDirty();
|
||||
|
||||
if (UEdGraphNode* Node = Cast<UEdGraphNode>(Obj))
|
||||
Nodes.Add(Node);
|
||||
|
||||
if (UEdGraph* Graph = Cast<UEdGraph>(Obj))
|
||||
Graphs.Add(Graph);
|
||||
|
||||
@@ -829,6 +833,8 @@ void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
|
||||
if (UMaterial* BaseMat = MatIface->GetMaterial())
|
||||
Materials.Add(BaseMat);
|
||||
}
|
||||
for (UEdGraphNode* Node : Nodes)
|
||||
Node->ReconstructNode();
|
||||
for (UEdGraph* Graph : Graphs)
|
||||
Graph->NotifyGraphChanged();
|
||||
for (UMaterial *Material : Materials)
|
||||
|
||||
Reference in New Issue
Block a user