#pragma once #include "CoreMinimal.h" #include "WingServer.h" #include "WingHandler.h" #include "WingTypes.h" #include "WingJson.h" #include "WingUtils.h" #include "StructUtils/UserDefinedStruct.h" #include "Kismet2/BlueprintEditorUtils.h" #include "UserDefinedStructure/UserDefinedStructEditorData.h" #include "Factories/StructureFactory.h" #include "WingPackageMaker.h" #include "Struct_Create.generated.h" // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- USTRUCT() struct FStructPropertyEntry { GENERATED_BODY() UPROPERTY() FString Name; UPROPERTY() FString Type; }; UCLASS() class UWing_Struct_Create : public UObject, public IWingHandler { GENERATED_BODY() public: UPROPERTY(meta=(Description="Full asset path for the new struct (e.g. '/Game/DataTypes/S_MyStruct')")) FString AssetPath; UPROPERTY(meta=(Optional, Description="Array of initial properties, each with 'name' and 'type' fields")) FWingJsonArray Properties; virtual FString GetDescription() const override { return TEXT("Create a new UserDefinedStruct asset with optional initial properties."); } virtual void Handle() override { WingPackageMaker Maker(AssetPath); if (!Maker.Ok()) return; // Create the struct using the AssetTools factory. UUserDefinedStruct* NewStruct = Maker.CreateAsset(); if (!NewStruct) return; // Add properties if specified. int32 PropsAdded = 0; for (const TSharedPtr& PropVal : Properties.Array) { FStructPropertyEntry Entry; if (!WingJson::PopulateFromJson(FStructPropertyEntry::StaticStruct(), &Entry, PropVal)) return; if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue; FEdGraphPinType PinType; if (!UWingTypes::TextToType(Entry.Type, PinType)) continue; // Snapshot existing GUIDs so we can find the newly added one. TSet ExistingGuids; for (const FStructVariableDescription& Var : FStructureEditorUtils::GetVarDesc(NewStruct)) ExistingGuids.Add(Var.VarGuid); if (!FStructureEditorUtils::AddVariable(NewStruct, PinType)) continue; // Find the new variable by diffing GUID sets. for (const FStructVariableDescription& Var : FStructureEditorUtils::GetVarDesc(NewStruct)) { if (!ExistingGuids.Contains(Var.VarGuid)) { FStructureEditorUtils::RenameVariable(NewStruct, Var.VarGuid, Entry.Name); break; } } PropsAdded++; } UWingServer::Printf(TEXT("Created %s\n"), *NewStruct->GetPathName()); if (PropsAdded > 0) UWingServer::Printf(TEXT("Properties added: %d\n"), PropsAdded); } };